feat(oci)!: make GlobalAccessPolicy optional and toggleable#2275
Conversation
Global access was previously always added for remote stores and had no way to be toggled from the repository configuration level. This adds a GlobalAccessPolicy to RepositoryOptions with two modes: - GlobalAccessPolicyDefault: only add global access for remote stores - GlobalAccessPolicyAlways: enforce global access on all local blobs Also fixes ResourceLocalBlobOCILayout which was not respecting the EnforceGlobalAccess option, unlike ResourceLocalBlobOCILayer. Signed-off-by: Jakob Möller <contact@jakob-moeller.com>
Extend both OCI and CTF repository specifications with a globalAccessPolicy field (string: "" or "always") that controls whether global access references are added to local blobs. The CachingComponentVersionRepositoryProvider now reads this field from repository specs and passes it through as a RepositoryOption when constructing repositories. Generated JSON schemas updated accordingly. Signed-off-by: Jakob Möller <contact@jakob-moeller.com>
CTF archives are local storage — global access references would be invalid since content is not globally reachable. Remove the field from CTF spec, provider wiring, and regenerate schemas. Signed-off-by: Jakob Möller <contact@jakob-moeller.com>
✅ Deploy Preview for ocm-website ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 14 minutes and 4 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
📝 WalkthroughWalkthroughIntroduced Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Replace EnforceGlobalAccess bool with three-valued GlobalAccessPolicy enum in pack.Options: - Default: auto-detect from storage backend (unchanged behavior) - Always: force global access on all blobs - Never: suppress global access even on remote registries This gives full control over global access at repository level via spec or Go API. Signed-off-by: Jakob Möller <contact@jakob-moeller.com>
Change zero value of GlobalAccessPolicy from Default (auto-detect) to Never (suppress) across all layers. This discourages reliance on global access references by making suppression opt-out rather than opt-in. Spec values: "" (never, default), "default" (auto-detect), "always". Go API: iota 0=Never, 1=Default, 2=Always. Signed-off-by: Jakob Möller <contact@jakob-moeller.com>
Remove GlobalAccessPolicyAlways — forcing global access on non-global backends produces invalid references and is not a valid use case. Rename GlobalAccessPolicyDefault to GlobalAccessPolicyAuto for clarity. Two values remain: - Never (zero value, default): suppress global access - Auto: auto-detect from storage backend Spec values: "" (never) and "auto". Signed-off-by: Jakob Möller <contact@jakob-moeller.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
bindings/go/oci/internal/pack/pack_test.go (1)
299-320: These additions still don't prove the policy is wired through.Both tables run against a local
filestore, the newnevercase uses the zero/default policy, and the layout table never setscheckGlobalAccess. If the policy were ignored in either code path, these assertions would still pass. Please add one case whereGlobalAccessactually flips based on the supplied policy/store combination.Also applies to: 753-812
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@bindings/go/oci/internal/pack/pack_test.go` around lines 299 - 320, The tests add a "never" GlobalAccessPolicy case but never demonstrate the policy actually toggles GlobalAccess; update the table-driven tests to include at least one pair of cases that differ only by Options.GlobalAccessPolicy (e.g., GlobalAccessPolicyNever vs GlobalAccessPolicyAlways) and run against the same store type so the result differs, then in the checkGlobalAccess callback assert that resource.Access.(*v2.LocalBlob).GlobalAccess is nil for the Never case and non-nil (or has the expected value) for the Always case; modify the test rows that use Options (AccessScheme, BaseReference, GlobalAccessPolicy) and the checkGlobalAccess functions to explicitly verify the flip so the wiring from Options.GlobalAccessPolicy to the produced descriptor.Resource is exercised.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@bindings/go/oci/internal/pack/pack.go`:
- Around line 57-61: The comment for Options.GlobalAccessPolicy is out of date:
update the doc for the GlobalAccessPolicy field (in type Options) to describe
the current enum values (GlobalAccessPolicy with values Never and Auto), state
that the zero value is Never (i.e., global access is suppressed by default), and
explain the behavior of Auto (auto-detects based on storage backend) and Never
(never add global access references). Ensure the text replaces references to the
removed Always mode and the incorrect zero-value behavior.
In `@bindings/go/oci/repository/provider/provider.go`:
- Around line 142-144: The code silently treats unknown globalAccessPolicy enum
strings as nil (effectively "never") instead of failing; update validation so
typos are rejected. Modify globalAccessPolicyFromOCI (or add a validator in
getConvertedTypedSpec) to return an error for any unrecognized
GlobalAccessPolicy value and propagate that error from getConvertedTypedSpec to
the caller instead of returning nil; update both call sites that append opts
(the block using globalAccessPolicyFromOCI at the shown lines and the similar
block around lines 195-201) to handle the error and fail fast when an unknown
enum is encountered.
---
Nitpick comments:
In `@bindings/go/oci/internal/pack/pack_test.go`:
- Around line 299-320: The tests add a "never" GlobalAccessPolicy case but never
demonstrate the policy actually toggles GlobalAccess; update the table-driven
tests to include at least one pair of cases that differ only by
Options.GlobalAccessPolicy (e.g., GlobalAccessPolicyNever vs
GlobalAccessPolicyAlways) and run against the same store type so the result
differs, then in the checkGlobalAccess callback assert that
resource.Access.(*v2.LocalBlob).GlobalAccess is nil for the Never case and
non-nil (or has the expected value) for the Always case; modify the test rows
that use Options (AccessScheme, BaseReference, GlobalAccessPolicy) and the
checkGlobalAccess functions to explicitly verify the flip so the wiring from
Options.GlobalAccessPolicy to the produced descriptor.Resource is exercised.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 8eb911fe-1c99-493f-9435-92e9be6fbcb9
📒 Files selected for processing (15)
bindings/go/oci/internal/pack/pack.gobindings/go/oci/internal/pack/pack_test.gobindings/go/oci/repository.gobindings/go/oci/repository/provider/provider.gobindings/go/oci/repository_options.gobindings/go/oci/spec/repository/v1/oci/repository.gobindings/go/oci/spec/repository/v1/oci/schemas/Repository.schema.jsonbindings/go/oci/spec/transformation/v1alpha1/schemas/OCIAddComponentVersion.schema.jsonbindings/go/oci/spec/transformation/v1alpha1/schemas/OCIAddComponentVersionSpec.schema.jsonbindings/go/oci/spec/transformation/v1alpha1/schemas/OCIAddLocalResource.schema.jsonbindings/go/oci/spec/transformation/v1alpha1/schemas/OCIAddLocalResourceSpec.schema.jsonbindings/go/oci/spec/transformation/v1alpha1/schemas/OCIGetComponentVersion.schema.jsonbindings/go/oci/spec/transformation/v1alpha1/schemas/OCIGetComponentVersionSpec.schema.jsonbindings/go/oci/spec/transformation/v1alpha1/schemas/OCIGetLocalResource.schema.jsonbindings/go/oci/spec/transformation/v1alpha1/schemas/OCIGetLocalResourceSpec.schema.json
Fix stale Options.GlobalAccessPolicy doc that still referenced removed Always mode. Make globalAccessPolicyFromOCI return error for unrecognized policy values instead of silently falling back to never. Signed-off-by: Jakob Möller <contact@jakob-moeller.com>
GlobalAccessPolicyAuto is carried over from OCM v1 for backwards compatibility. Mark it as experimental across all layers (Go API, pack internals, OCI repo spec) and note that its future availability is being evaluated by the community. Signed-off-by: Jakob Möller <contact@jakob-moeller.com>
Schemas still referenced "default" instead of "auto" after rename. Regenerate to match current spec constants. Signed-off-by: Jakob Möller <contact@jakob-moeller.com>
…spec Remove globalAccessPolicy from OCI Repository JSON serialization (field kept internal for plumbing via json:"-"). Add it to OCIAddLocalResourceSpec as the user-facing configuration point. Transformer sets policy on embedded repo struct before passing to provider. This scopes the experimental OCM v1 carry-over to transformers only, keeping repo spec clean. Regenerated JSON schemas reflect the move. Signed-off-by: Jakob Möller <contact@jakob-moeller.com>
Remove GlobalAccessPolicy from oci.Repository spec struct entirely. Policy now only configurable via OCIAddLocalResourceSpec transformer spec. Transformer applies policy via SetGlobalAccessPolicy on the concrete *oci.Repository after provider creates it. Provider no longer wires globalAccessPolicy — removed helper and validation. Type + constants remain in spec package for transformer import. Regenerated schemas. Signed-off-by: Jakob Möller <contact@jakob-moeller.com>
…ackage Move canonical GlobalAccessPolicy type + iota to internal/policy. Both oci and pack packages now alias from same source — no duplicate iota definitions. Remove type cast in repository.go since types match. Signed-off-by: Jakob Möller <contact@jakob-moeller.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@bindings/go/oci/transformer/add_local_resource.go`:
- Around line 101-113: The code currently skips applying a global access policy
when globalAccessPolicy == "" (documented as "Never"), which can leave a repo's
previous policy intact; update the logic that inspects globalAccessPolicy (and
the repo type assertion to *oci.Repository) to explicitly handle the empty
string case by calling
ociRepo.SetGlobalAccessPolicy(oci.GlobalAccessPolicyNever), and keep the
existing case for ocirepospecv1.GlobalAccessPolicyAuto ->
oci.GlobalAccessPolicyAuto and the default error path for unknown values so that
"" properly resets the repo policy instead of leaking prior state.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 7c058c64-672b-4611-a17f-7a66b28b2693
📒 Files selected for processing (6)
bindings/go/oci/repository.gobindings/go/oci/spec/repository/v1/oci/repository.gobindings/go/oci/spec/transformation/v1alpha1/oci_add_local_resource.gobindings/go/oci/spec/transformation/v1alpha1/schemas/OCIAddLocalResource.schema.jsonbindings/go/oci/spec/transformation/v1alpha1/schemas/OCIAddLocalResourceSpec.schema.jsonbindings/go/oci/transformer/add_local_resource.go
✅ Files skipped from review due to trivial changes (1)
- bindings/go/oci/spec/repository/v1/oci/repository.go
🚧 Files skipped from review as they are similar to previous changes (2)
- bindings/go/oci/repository.go
- bindings/go/oci/spec/transformation/v1alpha1/schemas/OCIAddLocalResource.schema.json
Apply policy explicitly (including Never) on every OCI transform to prevent cached repo instances from leaking prior auto policy. Skip type assertion for non-OCI repos when policy is Never (noop). Signed-off-by: Jakob Möller <contact@jakob-moeller.com>
Verify auto policy on non-remote store does not set global access, confirming auto-detect logic only activates for remote backends. Signed-off-by: Jakob Möller <contact@jakob-moeller.com>
Pack now uses policy.GlobalAccessPolicy directly instead of re-exporting type alias + constants. Single definition in internal/policy, oci package re-exports for public API only. Signed-off-by: Jakob Möller <contact@jakob-moeller.com>
…ponent-model#2275) ## Summary - Add `GlobalAccessPolicy` to `RepositoryOptions` with two modes: `Never` (disabled) and `Auto` (force global access on all local blobs if the repo supports it) - Wire through OCI repository spec (`globalAccessPolicy` JSON field) and provider - Fix bug: `ResourceLocalBlobOCILayout` was ignoring `EnforceGlobalAccess` (unlike `ResourceLocalBlobOCILayer`) - Remove `GlobalAccessPolicy` from CTF spec — CTF is local storage, global access references would be invalid ## Test plan - [x] New test: `ResourceLocalBlobOCILayout` with `EnforceGlobalAccess: true` - [x] All existing OCI tests pass - [x] Code generators (`task generate`) run clean - [x] Build compiles without errors --------- Signed-off-by: Jakob Möller <contact@jakob-moeller.com> Co-authored-by: Matthias Bruns <github@matthiasbruns.com>
…to v0.0.40 (#2331) (#2352) #### What this PR does / why we need it Adapts all consumers to the breaking change introduced in #2275: `GlobalAccessPolicy` now defaults to `Never`, meaning `localBlob` resources no longer have a `globalAccess` field populated after transfer. This upgrades `bindings/go/oci` from v0.0.39 to v0.0.40 and updates `go.mod`/`go.sum` across 8 consuming modules (constructor, helm, oci/integration, transfer, transfer/integration, cli, cli/integration, kubernetes/controller). **Test fixes:** - `transfer/integration`: Rewrites the `CopyModeAllResources` test — instead of verifying `globalAccess` is non-nil and resolvable in the target registry, it now asserts `globalAccess` is nil and verifies the blob is directly readable from the target repository via `GetLocalResource` - `cli/integration`: Replaces weak output assertions (checking registry addresses from `globalAccess` image references) with a stronger negative test that proves component-b is unreachable from registry-a without resolver config, confirming resolver routing actually works **Conformance scenario fixes:** - RGD: Replaces `resource.access.globalAccess.imageReference.toOCI()` with `resource.access.toOCI()`, which constructs the OCI reference directly from the component's repository spec and local reference digest - RGD: Uses `image.digest` instead of `image.tag` in HelmRelease values, since `toOCI()` on a `localBlob` returns only a digest reference (no tag) - RGD: Drops the `tag` field from `additionalStatusFields` — no longer available without `globalAccess` - Helm chart templates (notes + postgres): Switches image references from `:tag` to `@digest` format - Helm chart values: Replaces `tag` field with `digest` field **Documentation:** - Sovereign cloud ADR: Updates CEL expression examples from `resource.access.globalAccess.imageReference.toOCI()` to `resource.access.toOCI()` - OCM controllers concept page: Updates CEL example from `resource.access.globalAccess.imageReference.split('/')[0]` to `resource.access.toOCI().registry` #### How it was tested - Unit tests: all modules pass - Integration tests: `transfer/integration` and `cli/integration` pass - E2E tests: 12/12 pass on Kind cluster - Conformance scenario: passes with both the current CLI (`0.0.0-main`, which still populates `globalAccess`) and a locally-built CLI using OCI v0.0.40 (which does not) #### Which issue(s) this PR fixes Fixes #2331 --------- Signed-off-by: Frederic Wilhelm <frederic.wilhelm@sap.com> Co-authored-by: ocmbot[bot] <125909804+ocmbot[bot]@users.noreply.github.com> Co-authored-by: Matthias Bruns <github@matthiasbruns.com>
…to v0.0.40 (#2331) (#2352) #### What this PR does / why we need it Adapts all consumers to the breaking change introduced in #2275: `GlobalAccessPolicy` now defaults to `Never`, meaning `localBlob` resources no longer have a `globalAccess` field populated after transfer. This upgrades `bindings/go/oci` from v0.0.39 to v0.0.40 and updates `go.mod`/`go.sum` across 8 consuming modules (constructor, helm, oci/integration, transfer, transfer/integration, cli, cli/integration, kubernetes/controller). **Test fixes:** - `transfer/integration`: Rewrites the `CopyModeAllResources` test — instead of verifying `globalAccess` is non-nil and resolvable in the target registry, it now asserts `globalAccess` is nil and verifies the blob is directly readable from the target repository via `GetLocalResource` - `cli/integration`: Replaces weak output assertions (checking registry addresses from `globalAccess` image references) with a stronger negative test that proves component-b is unreachable from registry-a without resolver config, confirming resolver routing actually works **Conformance scenario fixes:** - RGD: Replaces `resource.access.globalAccess.imageReference.toOCI()` with `resource.access.toOCI()`, which constructs the OCI reference directly from the component's repository spec and local reference digest - RGD: Uses `image.digest` instead of `image.tag` in HelmRelease values, since `toOCI()` on a `localBlob` returns only a digest reference (no tag) - RGD: Drops the `tag` field from `additionalStatusFields` — no longer available without `globalAccess` - Helm chart templates (notes + postgres): Switches image references from `:tag` to `@digest` format - Helm chart values: Replaces `tag` field with `digest` field **Documentation:** - Sovereign cloud ADR: Updates CEL expression examples from `resource.access.globalAccess.imageReference.toOCI()` to `resource.access.toOCI()` - OCM controllers concept page: Updates CEL example from `resource.access.globalAccess.imageReference.split('/')[0]` to `resource.access.toOCI().registry` #### How it was tested - Unit tests: all modules pass - Integration tests: `transfer/integration` and `cli/integration` pass - E2E tests: 12/12 pass on Kind cluster - Conformance scenario: passes with both the current CLI (`0.0.0-main`, which still populates `globalAccess`) and a locally-built CLI using OCI v0.0.40 (which does not) #### Which issue(s) this PR fixes Fixes #2331 --------- Signed-off-by: Frederic Wilhelm <frederic.wilhelm@sap.com> Co-authored-by: ocmbot[bot] <125909804+ocmbot[bot]@users.noreply.github.com> Co-authored-by: Matthias Bruns <github@matthiasbruns.com> f71796b
Summary
GlobalAccessPolicytoRepositoryOptionswith two modes:Never(disabled) andAuto(force global access on all local blobs if the repo supports it)globalAccessPolicyJSON field) and providerResourceLocalBlobOCILayoutwas ignoringEnforceGlobalAccess(unlikeResourceLocalBlobOCILayer)GlobalAccessPolicyfrom CTF spec — CTF is local storage, global access references would be invalidTest plan
ResourceLocalBlobOCILayoutwithEnforceGlobalAccess: truetask generate) run clean