Skip to content

Commit

Permalink
Rule: internal-entrypoint (#784)
Browse files Browse the repository at this point in the history
Ensure internal rules aren't used as entrypoints.

Fixes #783

Signed-off-by: Anders Eknert <anders@styra.com>
  • Loading branch information
anderseknert authored Jun 3, 2024
1 parent 2c095e6 commit 86c28d7
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ The following rules are currently available:
| bugs | [if-empty-object](https://docs.styra.com/regal/rules/bugs/if-empty-object) | Empty object following `if` |
| bugs | [impossible-not](https://docs.styra.com/regal/rules/bugs/impossible-not) | Impossible `not` condition |
| bugs | [inconsistent-args](https://docs.styra.com/regal/rules/bugs/inconsistent-args) | Inconsistently named function arguments |
| bugs | [internal-entrypoint](https://docs.styra.com/regal/rules/bugs/internal-entrypoint) | Entrypoint can't be marked internal |
| bugs | [invalid-metadata-attribute](https://docs.styra.com/regal/rules/bugs/invalid-metadata-attribute) | Invalid attribute in metadata annotation |
| bugs | [leaked-internal-reference](https://docs.styra.com/regal/rules/bugs/leaked-internal-reference) | Outside reference to internal rule or function |
| bugs | [not-equals-in-loop](https://docs.styra.com/regal/rules/bugs/not-equals-in-loop) | Use of != in loop |
Expand Down
2 changes: 2 additions & 0 deletions bundle/regal/config/provided/data.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ rules:
level: error
inconsistent-args:
level: error
internal-entrypoint:
level: error
invalid-metadata-attribute:
level: error
leaked-internal-reference:
Expand Down
18 changes: 18 additions & 0 deletions bundle/regal/rules/bugs/internal_entrypoint.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# METADATA
# description: Entrypoint can't be marked internal
package regal.rules.bugs["internal-entrypoint"]

import rego.v1

import data.regal.ast
import data.regal.result

report contains violation if {
some rule in ast.rules
some annotation in rule.annotations

annotation.entrypoint == true
startswith(ast.ref_to_string(rule.head.ref), "_")

violation := result.fail(rego.metadata.chain(), result.location(rule.head))
}
42 changes: 42 additions & 0 deletions bundle/regal/rules/bugs/internal_entrypoint_test.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package regal.rules.bugs["internal-entrypoint_test"]

import rego.v1

import data.regal.ast
import data.regal.config

import data.regal.rules.bugs["internal-entrypoint"] as rule

test_fail_internal_entrypoint if {
module := ast.with_rego_v1(`
# METADATA
# entrypoint: true
_allow := true
`)

r := rule.report with input as module
r == {{
"category": "bugs",
"description": "Entrypoint can't be marked internal",
"level": "error",
"location": {"col": 1, "file": "policy.rego", "row": 9, "text": "_allow := true"},
"related_resources": [{
"description": "documentation",
"ref": config.docs.resolve_url("$baseUrl/$category/internal-entrypoint", "bugs"),
}],
"title": "internal-entrypoint",
}}
}

test_success_non_internal_entrypoint if {
module := ast.with_rego_v1(`
# METADATA
# entrypoint: true
allow := true
`)

r := rule.report with input as module
r == set()
}
62 changes: 62 additions & 0 deletions docs/rules/bugs/internal-entrypoint.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# internal-entrypoint

**Summary**: Entrypoint can't be marked internal

**Category**: Bugs

**Avoid**
```rego
package policy
import rego.v1
# METADATA
# entrypoint: true
_authorized if {
# some conditions
}
```

**Prefer**
```rego
package policy
import rego.v1
# METADATA
# entrypoint: true
allow if _authorized
_authorized if {
# some conditions
}
```

## Rationale

Rules marked as internal using the [underscore prefix convention](https://docs.styra.com/opa/rego-style-guide#optionally-use-leading-underscore-for-rules-intended-for-internal-use)
cannot be used as entrypoints, as entrypoints by definition are public. Either rename the rule to mark it as public,
or use another public rule as an entrypoint, which may reference the internal rule.

## Configuration Options

This linter rule provides the following configuration options:

```yaml
rules:
bugs:
internal-entrypoint:
# one of "error", "warning", "ignore"
level: error
```
## Related Resources
- Rego Style Guide: [Optionally, use leading underscore for rules intended for internal use](https://docs.styra.com/opa/rego-style-guide#optionally-use-leading-underscore-for-rules-intended-for-internal-use)
- Regal Docs: [no-defined-entrypoint](https://docs.styra.com/regal/rules/idiomatic/no-defined-entrypoint)
## Community
If you think you've found a problem with this rule or its documentation, would like to suggest improvements, new rules,
or just talk about Regal in general, please join us in the `#regal` channel in the Styra Community
[Slack](https://communityinviter.com/apps/styracommunity/signup)!
1 change: 1 addition & 0 deletions e2e/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ func TestLintAllViolations(t *testing.T) {
"implicit-future-keywords": {},
"use-if": {},
"use-contains": {},
"internal-entrypoint": {},
}

for _, category := range cfg.Rules {
Expand Down
6 changes: 6 additions & 0 deletions internal/embeds/schemas/regal-ast.json
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,12 @@
},
"rule": {
"properties": {
"annotations": {
"items": {
"$ref": "#/$defs/annotations"
},
"type": "array"
},
"default": {
"type": "boolean"
},
Expand Down

0 comments on commit 86c28d7

Please sign in to comment.