18 Commits

Author SHA1 Message Date
br0x2 4fa5d202a7 avoid predictable OCI temp store (#8853)
### Why the changes in this PR are needed?

The OCI bundle and discovery download paths used a deterministic default
OCI store under the process temp directory when `persistence_directory`
was
not configured. In a shared temp directory, that made the store location
predictable before OPA initialized the local OCI layout.

This PR follows up on a report discussed with the OPA maintainers, where
Anders Eknert confirmed this can be handled as a regular public issue/PR
because it assumes local access to the system.

### What are the changes in this PR?

This changes the non-persistent default OCI store handling so OPA no
longer
uses a fixed shared temp path for bundle/discovery OCI downloads. When
callers
do not provide a store path, `download.NewOCI` now creates a private
temporary
OCI store directory.

The existing `persistence_directory` behavior is preserved: when
configured,
OPA still stores OCI state below `<persistence_directory>/oci`.

This also adds regression coverage for the default and explicit OCI
store path
behavior.

### Notes to assist PR review:

Tested with:

```bash
GOMODCACHE=/ssd1/CCS/recurbug/verifies/build/go-mod-cache GOCACHE=/tmp/opa-gocache /tmp/opa-go/go/bin/go test ./v1/download ./v1/plugins/bundle ./v1/plugins/discovery
```

### Further comments:

I kept this PR focused on the default non-persistent OCI store path and
did
not include unrelated bundle or discovery refactoring.

---------

Signed-off-by: kimdu0 <dino700072@gmail.com>
Signed-off-by: Sebastian Spaink <sebastianspaink@gmail.com>
Co-authored-by: kimdu0 <dino700072@gmail.com>
Co-authored-by: Sebastian Spaink <sebastianspaink@gmail.com>
2026-08-10 21:34:17 +00:00
Stephan Renatus cb54e9c14f runtime: rule labels metadata processing follow-ups (#8613)
 We now parse rego metadata annotations by default.

Rule annotations now support a `labels` field. During policy eval,
labels from all successfully evaluated rules are collected and included
in each decision log entry as a top-level `rule_labels` array. Each
element preserves the label map from one evaluated rule. Exact
duplicates are omitted.

```rego
# METADATA
# labels:
#   severity: low
#   team: platform
allow if input.role == "admin"
```

The resulting decision log entry will contain:

```json
{"rule_labels": [{"severity": "low", "team": "platform"}]}
```

---------

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2026-05-08 15:00:26 +00:00
Stephan Renatus dce01172d7 ast+rego+topdown: external rule source support (#8600)
External rule sources let wrapping projects inject rules at evaluation
time instead of compile time. The compiler marks external packages in
the rule tree but doesn't index them. When topdown hits an external
node, it calls Lookup to get rules, compiles them on the fly with a
scoped compiler, grafts the result into the tree, and caches it for the
duration of the evaluation.

Sources can be isolated (default, no access to surrounding policy) or
non-isolated (can reference static rules and other external sources).
The ExternalRuleIndexCloser interface handles cleanup after evaluation.
Precompiled rules can skip compiler stages via SkippedStages to avoid
redundant work.

This includes:
* hooks: add BundlePreActivate hook This one is handy when registering
external sources.

* topdown: catch `ir == nil` rule index result
This wouldn't ordinarily happen: the compiler is checking refs before.
But in our use case, the SP rules may be configured to be able to reach
into the surrounding Rego (non-isolated mode). If that happens, the IR
lookup may indeed end up as `nil, nil`.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2026-05-05 09:48:50 +02:00
Anders Eknert 037101cd7c Linter configuration cleanup (#8397)
And enable more staticcheck linters. I saw staticcheck failures
mentioned in another PR, so thought I'd check it out.

- `WriteString(fmt.Sprintf)` -> `fmt.Fprintf`
- Rewrite calls to deprecated `*Rule.Path()`
- Don't use `==` to compare `time.Time`
- Use inline ignores over config exclusions of paths
- Remove 'varcheck' ignores as no longer used
- Remove v0 topdown/graphql.go (!)

Signed-off-by: Anders Eknert <anders.eknert@apple.com>
2026-03-06 22:07:35 +00:00
Sebastian Spaink 95280c0fcf allow multiple calls to config.ValidateAndInjectDefaults (#8216)
Add a separate field to keep track of the parsed min and max interval keeping the original fields to represent the user provided values. This prevents multiple calls to config.ValidateAndInjectDefaults from overflowing the values but still makes sure that the value has been converted at least once.

Signed-off-by: Sebastian Spaink <sebastianspaink@gmail.com>
2026-01-14 19:37:26 +00:00
jhjang b5cd718806 plugins/bundle: prevent ns-level polling by validating intervals (#8082)
Fix polling interval validation in Reconfigure to avoid nanosecond ticker
loops

Signed-off-by: jjhwan.h <gegeo@kakao.com>
2025-12-02 09:52:24 -06:00
Anders Eknert e03ac2f200 Bump golangci-lint, more gocritic linters (#8052)
- Bump golangci-lint -> 2.6.2
- Fix all `deprecatedComment` "notices should be in a dedicated paragraph, separated from the rest" reports
- Enable `appendCombine` and fix all "appendCombine: can combine chain of X appends into one" notices
- Enable `preferFprint` and fix the few reported issues
- Fix various issues reported only once or twice, like `zeroByteRepeat`

Signed-off-by: Anders Eknert <anders.eknert@apple.com>
2025-11-17 11:08:39 +01:00
Sebastian Spaink 7e4a0202c4 plugins/bundle: return callback error (#7871)
Updates the Bundle Plugins oneShot callback function signature used by Downloader, OCIDownloader, and fileLoader to return an error. This allows any issues in the callback function such as Rego parsing issues to be returned.

Signed-off-by: Sebastian Spaink <sebastianspaink@gmail.com>
2025-09-12 20:05:50 -05:00
Charlie Egan 11e52c4df6 v1/plugins: Address race in config access (#7825)
* v1/plugins: Address race in config access

I ran into this race condition on another PR:

https://github.com/open-policy-agent/opa/actions/runs/16655603110/job/47139789057

I have tried to make all manager.Config access thread-safe by adding new
getters for used values. GetConfig is regrettably based on a JSON
roundtrip deep copy of the config. This us used in tests (fine) but also
in the discovery plugin:

https://github.com/open-policy-agent/opa/blob/2d014a89bbbc307d7204817220146ffae992e838/v1/plugins/discovery/discovery.go#L122

getPluginSet is very tightly coupled to the manager.Config and because
of it's dependencies on status and the other plugins packages, it's hard
to break out.

So, for now, I think this is an improvement and worth getting a second
opinion on before more refactoring.

Signed-off-by: Charlie Egan <charlie@styra.com>

* v1/config: Use add Clone to config

This makes the use of the manager's config more thread-safe and
consistent without more API changes.

Signed-off-by: Charlie Egan <charlie@styra.com>

* topdown: Add clone() funcs for config structs

NamedValueCacheConfig.Clone, InterQueryBuiltinValueCacheConfig.Clone and
InterQueryBuiltinCacheConfig.Clone have been added.

All Clone methods return a deep copy of the struct. This is tested for
missed new fields using PopulateAllFields, a generic function that
stuffs structs with values for all fields.

Signed-off-by: Charlie Egan <charlie@styra.com>

* plugins: Clone new config

Signed-off-by: Charlie Egan <charlie@styra.com>

---------

Signed-off-by: Charlie Egan <charlie@styra.com>
2025-08-13 12:24:16 +00:00
Philip Conrad 5a872a4166 bundle: Add support for bundle store and activation plugins. (#7771)
This commit adds support for changing out how bundle storage and
activation work. To allow swapping out bundle activation, two new
`bundle` package functions are provided:

 - `RegisterActivator`: Registers a bundle.Activator with a string ID.
 - `RegisterDefaultBundleActivator`: Sets the default bundle.Activator to
   use by ID.

Behind the scenes, a few new `bundle` package variables are used to
track what bundle activators are available, and which is the preferred
default.

This system allows registering many activators, and allows choosing the
bundle activator to use at activation time. The activator to use is
decided in the following order:

 - `(bundle.ActivateOpts).Plugin` is used when non-nil.
 - `bundle.bundleExtActivator` is used when an ID was set with
   `RegisterDefaultBundleActivator`.
 - The default/original bundle activator is used if no other selection
   was made.

To support swapping out bundle storage (useful when testing new bundle
designs), a new `bundle` package function is provided:

 - `RegisterStoreFunc`: Sets the function to use for creating bundle
   storage.

These two features together allow swapping out most of the bundle
activation flow, without requiring deep modification of the `bundle`
package. Lazy bundle loading mode is also enabled across many CLI
commands and other bundle loading points now when a non-default bundle
activator is set.

Signed-off-by: Philip Conrad <philip@chariot-chaser.net>
Co-authored-by: Ashutosh Narkar <anarkar4387@gmail.com>
2025-07-17 17:23:12 +00:00
Anders Eknert 8ba08ac80c Apply modernize linter fixes (#7599)
Following up on #7566, and now applying the more exciting
modernizations. fmt.Appendf was new to me! But especially
the contains checks are so much better IMHO. I have reviewed
all changes myself and did a few manual changes where it
became obvious that things could be improved a little further.

(the modernize analyzer still has some issues running against
OPA, and I have manually worked around those for the time being)

Signed-off-by: Anders Eknert <anders@styra.com>
2025-05-20 23:12:13 +02:00
Anders Eknert e43ef0a979 Use any in place of interface{} (#7566)
Earlier this evening I tried to run the Go
[modernize](https://pkg.go.dev/golang.org/x/tools/gopls/internal/analysis/modernize)
analyzer on OPA. That didn't go as planned:

- https://github.com/golang/go/issues/73661
- https://github.com/golang/go/issues/73663

While we wait for that to be fixed, I figured an old-fashioned
search-and-replace across the repo may work for at least the
`interface{}` to `any` conversion. That should help make it easier
to see the other fixes as applied by the modernize tool once it has
had those issues resolved.

Signed-off-by: Anders Eknert <anders@styra.com>
2025-05-12 13:57:48 +02:00
Anders Eknert bd5ceb5142 Enable unused-receiver linter (revive) (#7448)
Signed-off-by: Anders Eknert <anders@styra.com>
2025-03-14 11:41:25 +01:00
Anders Eknert afb30d3f9d Add gocritic linter, fix a bunch of stuff (#7377)
Brace yourselves! For there are many touched files here. No changes
in semantics however.

Spent a long time trying out the various optional rules gocritic
provides, and settled for a few of them. There are more I really
like, but that would take many hours to address across the codebase.

Perhaps others find gocritic too pedantic? If so, we can merge the
fixes without enabling the rule.

Signed-off-by: Anders Eknert <anders@styra.com>
2025-02-24 16:28:41 +01:00
Anders Eknert b942136a4a Use Go 1.22+ int ranges (#7328)
With "some" help from `golangci-lint run --fix ./...`

Signed-off-by: Anders Eknert <anders@styra.com>
2025-01-30 09:57:27 +01:00
Johan Fylling b032e3bfc0 Fixing issue where bundle plugin could panic on reconfiguration (SDK use) (#7300)
Fixing issue where bundle plugin would panic on reconfiguration if module rego-version is missing in bundle manifest.

* Passing runtime rego-version to deactivation options
* Preferring to pull rego-version from parsed modules if present

This solves an edge case when using the OPA SDK, and should not affect standalone OPA.

Fixes: #7297
Signed-off-by: Johan Fylling <johan.dev@fylling.se>
2025-01-24 13:47:16 +01:00
Shiqi Yang fb317c5bc4 perf: optimize activation of bundles with no inter-bundle path overlap (#7155)
Fixes: #7144

Signed-off-by: Shiqi Yang <syang482@bloomberg.net>
2025-01-08 14:32:31 +01:00
Johan Fylling 7bb6dbe36b Preparing for v1 API
Moving (most) source to v1 root package to prepare for v0/v1 API separation.

Signed-off-by: Johan Fylling <johan.dev@fylling.se>
2024-12-12 15:09:03 +01:00