Skip to content

feat: typed oci credentials and identity (Phase 2)#2360

Merged
matthiasbruns merged 33 commits into
open-component-model:mainfrom
matthiasbruns:feat/704_typed_credential_oci
May 4, 2026
Merged

feat: typed oci credentials and identity (Phase 2)#2360
matthiasbruns merged 33 commits into
open-component-model:mainfrom
matthiasbruns:feat/704_typed_credential_oci

Conversation

@matthiasbruns

@matthiasbruns matthiasbruns commented Apr 22, 2026

Copy link
Copy Markdown
Contributor

What this PR does / why we need it

Phase 2 typed oci bindings ADR

Which issue(s) this PR fixes

Contributes: open-component-model/ocm-project#986

You can see the whole picture in #2148

Testing

How to test the changes

Unit & integration tests only.

I ran task init/go.work with the updated credentials binding to see if the update breaks ocm - it does not :)

Verification
  • I have added/updated tests for my changes (see Test Requirements)
  • Tests pass locally (task test and task test/integration if applicable)
  • My changes do not decrease test coverage

@netlify

netlify Bot commented Apr 22, 2026

Copy link
Copy Markdown

Deploy Preview for ocm-website ready!

Name Link
🔨 Latest commit ff80c5d
🔍 Latest deploy log https://app.netlify.com/projects/ocm-website/deploys/69f88ef434719d0008f918cb
😎 Deploy Preview https://deploy-preview-2360--ocm-website.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai

coderabbitai Bot commented Apr 22, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This PR implements Phase 1 (Foundation) of typed credentials (ADR 0017) by introducing OCICredentials and OCIRegistryIdentity types, adding a resolveCredentialsMap helper that bridges typed and untyped credential resolution, and refactoring all OCI transformers to use ResolveTyped instead of directly calling Resolve.

Changes

Typed Credentials Foundation and Resolution

Layer / File(s) Summary
Data Shapes
bindings/go/oci/spec/credentials/v1/oci_credentials.go, bindings/go/oci/spec/identity/v1/oci_registry_identity.go
New OCICredentials struct with typed fields (Username, Password, AccessToken, RefreshToken) and OCIRegistryIdentity struct with registry details (Hostname, Scheme, Port, Path); both include credential/identity key constants (canonical camelCase and deprecated snake_case).
Type Registration & Conversion
bindings/go/oci/spec/credentials/v1/oci_credentials.go, bindings/go/oci/spec/identity/v1/register.go, bindings/go/oci/spec/identity/v1/type.go
Registration functions and versioned type constants for OCICredentials and OCIRegistryIdentity; FromDirectCredentials converts map[string]string to typed credentials with fallback logic for legacy keys.
Runtime Integration
bindings/go/oci/spec/credentials/v1/zz_generated.ocm_type.go, bindings/go/oci/spec/credentials/v1/zz_generated.ocm_jsonschema.go, bindings/go/oci/spec/identity/v1/zz_generated.ocm_type.go, bindings/go/oci/spec/identity/v1/zz_generated.ocm_jsonschema.go, bindings/go/oci/spec/credentials/v1/zz_generated.deepcopy.go, bindings/go/oci/spec/identity/v1/zz_generated.deepcopy.go
Auto-generated SetType/GetType, JSONSchema(), and deep-copy methods for both credential and identity types; enable runtime scheme integration and serialization.
Schema Definitions
bindings/go/oci/spec/credentials/v1/schemas/OCICredentials.schema.json, bindings/go/oci/spec/identity/v1/schemas/OCIRegistryIdentity.schema.json
JSON Schemas defining structure, required fields (type), allowed properties, and deprecated type aliases for both credential and identity objects.
Credential Resolution Refactoring
bindings/go/oci/transformer/credentials.go
New resolveCredentialsMap helper that calls ResolveTyped on identity, converts typed credentials to map[string]string, handles credentials.ErrNotFound gracefully, and errors on unsupported types.
Transformer Integration
bindings/go/oci/transformer/add_component_version.go, bindings/go/oci/transformer/add_local_resource.go, bindings/go/oci/transformer/add_oci_artifact.go, bindings/go/oci/transformer/get_component_version.go, bindings/go/oci/transformer/get_local_resource.go, bindings/go/oci/transformer/get_oci_artifact.go
Updated credential resolution to use resolveCredentialsMap instead of CredentialProvider.Resolve; removed error suppression for credentials.ErrNotFound, causing all resolution errors to fail transforms.
Import Path Updates
bindings/go/oci/credentials/docker_config.go, bindings/go/oci/repository/provider/provider.go, bindings/go/oci/repository/resource/resource_repository.go
Sourced credential key constants from typed credentialsv1 package; updated identity imports from spec/credentials/identity/v1 to spec/identity/v1.
Tests & Validation
bindings/go/oci/spec/credentials/v1/oci_credentials_test.go, bindings/go/oci/spec/identity/v1/oci_registry_identity_test.go, bindings/go/oci/spec/identity/v1/oci_registry_identity_test.go, bindings/go/oci/transformer/credentials_test.go, bindings/go/oci/transformer/add_oci_artifact_test.go
Comprehensive tests verifying type registration, scheme conversion round-trips, credential mapping with fallback logic, empty field handling, error propagation, and mock credential resolver behavior.

Sequence Diagram

sequenceDiagram
    participant T as OCI Transformer<br/>(e.g., GetOCIArtifact)
    participant R as resolveCredentialsMap
    participant CR as Credential Resolver<br/>(ResolveTyped)
    participant S as Runtime Scheme<br/>(Credential Provider)
    
    T->>R: resolveCredentialsMap(ctx, identity)
    R->>CR: ResolveTyped(identity)
    CR->>S: Lookup typed credential<br/>in config/scheme
    S-->>CR: *OCICredentials or<br/>*DirectCredentials
    CR-->>R: typed credential
    
    alt OCICredentials
        R->>R: Extract Username,<br/>Password, Tokens
        R->>R: Build map[string]string
        R-->>T: credentials map
    else DirectCredentials
        R->>R: Clone Properties
        R-->>T: properties map
    else ErrNotFound
        R-->>T: nil, nil<br/>(no error)
    else Unsupported Type
        R-->>T: nil,<br/>error: "unsupported"
    end
    
    T->>T: Use credentials map<br/>in transform operation
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • PR #2343: Implements the typed credentials foundation interfaces (CredentialTypeSchemeProvider, IdentityTypeSchemeProvider, CredentialAcceptor) in the credential graph that this PR depends on.
  • PR #1890: Updates OCI identity type usage to reference the new spec/identity/v1 package instead of legacy credentials identity paths.
  • PR #2055: Modifies OCI credential resolution logic and key constants, directly consumed by the typed credential conversion introduced here.

Suggested reviewers

  • frewilhelm
  • fabianburth
  • jakobmoellerdev

🐰 A rabbit hops through the repo with glee,
Typed credentials now flow wild and free!
No more mystery strings in the code,
Identity and tokens, neatly bestowed!
From maps into structs, the refactor's complete, ✨🔐

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.73% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: typed oci credentials and identity (Phase 2)' clearly summarizes the main change: implementing Phase 2 of typed OCI bindings for credentials and identity.
Linked Issues check ✅ Passed The PR addresses Phase 1 foundation requirements (#704): adds ResolveTyped support, introduces CredentialTypeSchemeProvider/IdentityTypeSchemeProvider interfaces, registers DirectCredentials/v1 fallback, and implements typed OCI credentials and identity structs with registration, conversion, and deep-copy methods.
Out of Scope Changes check ✅ Passed All changes focus on Phase 2 OCI binding implementation: credential/identity types, registration, conversions, transformers using ResolveTyped, and tests. No unrelated modifications detected outside the linked issue scope.
Description check ✅ Passed The PR description clearly relates to the changeset, explaining Phase 2 typed OCI bindings implementation following ADR guidelines with test coverage verification.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added kind/feature new feature, enhancement, improvement, extension size/l Large labels Apr 22, 2026
@matthiasbruns matthiasbruns force-pushed the feat/704_typed_credential_oci branch from a7f8b13 to f956f7f Compare April 22, 2026 09:57
@fabianburth fabianburth changed the title feat: typed oci credentils and identity feat: typed oci credentials and identity Apr 24, 2026
@matthiasbruns matthiasbruns force-pushed the feat/704_typed_credential_oci branch from f956f7f to ac7090e Compare April 28, 2026 13:37
@github-actions github-actions Bot added the area/documentation Documentation related label Apr 28, 2026
@matthiasbruns matthiasbruns force-pushed the feat/704_typed_credential_oci branch from 341efd6 to 606ee13 Compare April 29, 2026 08:25
Comment thread bindings/go/oci/credentials/docker_config.go
@matthiasbruns matthiasbruns force-pushed the feat/704_typed_credential_oci branch from a930ef8 to 3ab33dd Compare April 29, 2026 17:04
@matthiasbruns matthiasbruns marked this pull request as ready for review April 29, 2026 17:29
@matthiasbruns matthiasbruns requested a review from a team as a code owner April 29, 2026 17:29
@matthiasbruns matthiasbruns changed the title feat: typed oci credentials and identity feat: typed oci credentials and identity (Phase 2) Apr 29, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
bindings/go/oci/spec/credentials/identity/v1/oci_registry_identity_test.go (1)

45-48: Also assert Type survives round-trip conversion.

Line 31 initializes Type, but the current assertions only verify auxiliary fields. Adding a Type assertion will catch regressions in typed identity conversion behavior.

✅ Suggested test addition
 	assert.Equal(t, original.Hostname, restored.Hostname)
 	assert.Equal(t, original.Scheme, restored.Scheme)
 	assert.Equal(t, original.Port, restored.Port)
 	assert.Equal(t, original.Path, restored.Path)
+	assert.Equal(t, original.Type, restored.Type)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bindings/go/oci/spec/credentials/identity/v1/oci_registry_identity_test.go`
around lines 45 - 48, Add an assertion that verifies the identity Type survives
round-trip conversion by asserting original.Type equals restored.Type in the
same test that already checks Hostname, Scheme, Port, and Path (look for the
variables original and restored in oci_registry_identity_test.go); update the
assertions block to include assert.Equal(t, original.Type, restored.Type) so
regressions in typed identity conversion are caught.
bindings/go/oci/transformer/credentials_test.go (1)

42-45: Prefer credential key constants over string literals in assertions.

Using ocicredsv1.CredentialKey* constants here will keep tests resilient to key renames.

♻️ Suggested assertion update
-	assert.Equal(t, "user", creds["username"])
-	assert.Equal(t, "pass", creds["password"])
-	assert.Equal(t, "tok", creds["accessToken"])
-	assert.Equal(t, "ref", creds["refreshToken"])
+	assert.Equal(t, "user", creds[ocicredsv1.CredentialKeyUsername])
+	assert.Equal(t, "pass", creds[ocicredsv1.CredentialKeyPassword])
+	assert.Equal(t, "tok", creds[ocicredsv1.CredentialKeyAccessToken])
+	assert.Equal(t, "ref", creds[ocicredsv1.CredentialKeyRefreshToken])
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bindings/go/oci/transformer/credentials_test.go` around lines 42 - 45,
Replace the string literal keys used in the assertions with the ocicredsv1
credential key constants to make tests robust to renames: change accesses of
creds["username"], creds["password"], creds["accessToken"], and
creds["refreshToken"] in the test (where the variable creds is asserted) to use
ocicredsv1.CredentialKeyUsername, ocicredsv1.CredentialKeyPassword,
ocicredsv1.CredentialKeyAccessToken, and ocicredsv1.CredentialKeyRefreshToken
respectively so the assert.Equal calls reference the constant keys.
bindings/go/oci/spec/credentials/v1/oci_credentials_test.go (1)

104-110: Cover the unversioned alias in the registration test.

MustRegisterCredentialType advertises backward compatibility by registering both OCICredentials/v1 and OCICredentials, but this test only exercises the versioned path. Adding an assertion for runtime.NewUnversionedType(OCICredentialsType) would protect the alias contract from regressing unnoticed.

Suggested test addition
 func TestMustRegisterCredentialType(t *testing.T) {
 	scheme := runtime.NewScheme()
 	MustRegisterCredentialType(scheme)

 	obj, err := scheme.NewObject(runtime.NewVersionedType(OCICredentialsType, Version))
 	require.NoError(t, err)
 	assert.IsType(t, &OCICredentials{}, obj)
+
+	obj, err = scheme.NewObject(runtime.NewUnversionedType(OCICredentialsType))
+	require.NoError(t, err)
+	assert.IsType(t, &OCICredentials{}, obj)
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bindings/go/oci/spec/credentials/v1/oci_credentials_test.go` around lines 104
- 110, The test TestMustRegisterCredentialType only verifies the versioned
registration; update it to also exercise the unversioned alias by calling
scheme.NewObject(runtime.NewUnversionedType(OCICredentialsType)) after
MustRegisterCredentialType and assert no error and that the returned object is
of type *OCICredentials; this ensures MustRegisterCredentialType registers both
runtime.NewVersionedType(OCICredentialsType, Version) and the unversioned alias.
bindings/go/oci/transformer/credentials.go (1)

34-35: Return a copy of DirectCredentials.Properties.

This branch leaks the resolver-owned map as-is. Unlike the OCICredentials path, any downstream normalization or augmentation of the returned credentials would mutate the stored DirectCredentials instance and affect later resolutions.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bindings/go/oci/transformer/credentials.go` around lines 34 - 35, The
DirectCredentials branch currently returns the resolver-owned map directly (case
*credconfigv1.DirectCredentials: return c.Properties, nil), which leaks internal
state; modify the branch to return a shallow copy of c.Properties instead
(create a new map, copy each key/value from c.Properties into it) so callers can
mutate the returned map without affecting the stored DirectCredentials instance
— mirror the safe behavior used in the OCICredentials path by returning the
cloned map and nil error.
🤖 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/spec/credentials/v1/oci_credentials.go`:
- Around line 39-52: The schema enum for the OCICredentials.Type field only
lists the versioned value but the scheme registers both the versioned and
unversioned aliases in MustRegisterCredentialType; update the Type field's
annotation (the // +ocm:jsonschema-gen:enum on OCICredentials.Type) to include
the deprecated unversioned name (e.g., add "OCICredentials" alongside
"OCICredentials/v1"), so the generated JSON schema accepts the alias, or
alternatively remove the unversioned registration call in
MustRegisterCredentialType if you intend to forbid the alias—modify either the
OCICredentials struct annotation or the alias registration in
MustRegisterCredentialType accordingly.

---

Nitpick comments:
In `@bindings/go/oci/spec/credentials/identity/v1/oci_registry_identity_test.go`:
- Around line 45-48: Add an assertion that verifies the identity Type survives
round-trip conversion by asserting original.Type equals restored.Type in the
same test that already checks Hostname, Scheme, Port, and Path (look for the
variables original and restored in oci_registry_identity_test.go); update the
assertions block to include assert.Equal(t, original.Type, restored.Type) so
regressions in typed identity conversion are caught.

In `@bindings/go/oci/spec/credentials/v1/oci_credentials_test.go`:
- Around line 104-110: The test TestMustRegisterCredentialType only verifies the
versioned registration; update it to also exercise the unversioned alias by
calling scheme.NewObject(runtime.NewUnversionedType(OCICredentialsType)) after
MustRegisterCredentialType and assert no error and that the returned object is
of type *OCICredentials; this ensures MustRegisterCredentialType registers both
runtime.NewVersionedType(OCICredentialsType, Version) and the unversioned alias.

In `@bindings/go/oci/transformer/credentials_test.go`:
- Around line 42-45: Replace the string literal keys used in the assertions with
the ocicredsv1 credential key constants to make tests robust to renames: change
accesses of creds["username"], creds["password"], creds["accessToken"], and
creds["refreshToken"] in the test (where the variable creds is asserted) to use
ocicredsv1.CredentialKeyUsername, ocicredsv1.CredentialKeyPassword,
ocicredsv1.CredentialKeyAccessToken, and ocicredsv1.CredentialKeyRefreshToken
respectively so the assert.Equal calls reference the constant keys.

In `@bindings/go/oci/transformer/credentials.go`:
- Around line 34-35: The DirectCredentials branch currently returns the
resolver-owned map directly (case *credconfigv1.DirectCredentials: return
c.Properties, nil), which leaks internal state; modify the branch to return a
shallow copy of c.Properties instead (create a new map, copy each key/value from
c.Properties into it) so callers can mutate the returned map without affecting
the stored DirectCredentials instance — mirror the safe behavior used in the
OCICredentials path by returning the cloned map and nil error.
🪄 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: 59923ba1-c477-49bd-bd88-58515ab944cd

📥 Commits

Reviewing files that changed from the base of the PR and between bf0b7e5 and 3ab33dd.

📒 Files selected for processing (24)
  • bindings/go/oci/credentials/docker_config.go
  • bindings/go/oci/spec/credentials/identity/v1/oci_registry_identity.go
  • bindings/go/oci/spec/credentials/identity/v1/oci_registry_identity_test.go
  • bindings/go/oci/spec/credentials/identity/v1/register.go
  • bindings/go/oci/spec/credentials/identity/v1/schemas/OCIRegistryIdentity.schema.json
  • bindings/go/oci/spec/credentials/identity/v1/type.go
  • bindings/go/oci/spec/credentials/identity/v1/zz_generated.deepcopy.go
  • bindings/go/oci/spec/credentials/identity/v1/zz_generated.ocm_jsonschema.go
  • bindings/go/oci/spec/credentials/identity/v1/zz_generated.ocm_type.go
  • bindings/go/oci/spec/credentials/v1/oci_credentials.go
  • bindings/go/oci/spec/credentials/v1/oci_credentials_test.go
  • bindings/go/oci/spec/credentials/v1/schemas/OCICredentials.schema.json
  • bindings/go/oci/spec/credentials/v1/zz_generated.deepcopy.go
  • bindings/go/oci/spec/credentials/v1/zz_generated.ocm_jsonschema.go
  • bindings/go/oci/spec/credentials/v1/zz_generated.ocm_type.go
  • bindings/go/oci/transformer/add_component_version.go
  • bindings/go/oci/transformer/add_local_resource.go
  • bindings/go/oci/transformer/add_oci_artifact.go
  • bindings/go/oci/transformer/add_oci_artifact_test.go
  • bindings/go/oci/transformer/credentials.go
  • bindings/go/oci/transformer/credentials_test.go
  • bindings/go/oci/transformer/get_component_version.go
  • bindings/go/oci/transformer/get_local_resource.go
  • bindings/go/oci/transformer/get_oci_artifact.go

Comment thread bindings/go/oci/spec/credentials/v1/oci_credentials.go
matthiasbruns pushed a commit to matthiasbruns/open-component-model that referenced this pull request Apr 29, 2026
Add the deprecated unversioned enum value (OCICredentials) to the Type field annotation
to match the alias registration in MustRegisterCredentialType. This ensures the
generated JSON schema accepts the unversioned alias, which is already supported
by the runtime scheme.

Addresses CodeRabbit comment: open-component-model#2360 (comment)
On-behalf-of: SAP <matthias.bruns@sap.com>
Signed-off-by: Matthias Bruns <git@matthiasbruns.com>

# Conflicts:
#	bindings/go/credentials/go.sum

# Conflicts:
#	bindings/go/credentials/graph.go
#	bindings/go/credentials/ingest.go
#	bindings/go/credentials/ingest_test.go
#	bindings/go/credentials/interface.go
#	bindings/go/credentials/resolve_direct.go
#	bindings/go/credentials/resolve_indirect.go
#	bindings/go/credentials/resolve_static.go
#	bindings/go/credentials/spec/config/v1/config.go
#	bindings/go/credentials/type_registry.go
On-behalf-of: SAP <matthias.bruns@sap.com>
Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
On-behalf-of: SAP <matthias.bruns@sap.com>
Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
On-behalf-of: SAP <matthias.bruns@sap.com>
Signed-off-by: Matthias Bruns <git@matthiasbruns.com>

# Conflicts:
#	bindings/go/runtime/registry.go
#	bindings/go/runtime/registry_test.go
On-behalf-of: SAP <matthias.bruns@sap.com>
Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
On-behalf-of: SAP <matthias.bruns@sap.com>
Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
On-behalf-of: SAP <matthias.bruns@sap.com>
Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
On-behalf-of: SAP <matthias.bruns@sap.com>
Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
On-behalf-of: SAP <matthias.bruns@sap.com>
Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
On-behalf-of: SAP <matthias.bruns@sap.com>
Signed-off-by: Matthias Bruns <git@matthiasbruns.com>

# Conflicts:
#	bindings/go/oci/transformer/add_component_version.go
#	bindings/go/oci/transformer/add_local_resource.go
#	bindings/go/oci/transformer/add_oci_artifact.go
#	bindings/go/oci/transformer/add_oci_artifact_test.go
#	bindings/go/oci/transformer/get_component_version.go
#	bindings/go/oci/transformer/get_local_resource.go
#	bindings/go/oci/transformer/get_oci_artifact.go
On-behalf-of: SAP <matthias.bruns@sap.com>
Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
On-behalf-of: SAP <matthias.bruns@sap.com>
Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
On-behalf-of: SAP <matthias.bruns@sap.com>
Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
On-behalf-of: SAP <matthias.bruns@sap.com>
Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
Comment thread bindings/go/oci/spec/credentials/v1/oci_credentials.go Outdated
matthiasbruns and others added 2 commits May 4, 2026 07:49
On-behalf-of: SAP <matthias.bruns@sap.com>
Signed-off-by: Matthias Bruns <git@matthiasbruns.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
bindings/go/oci/transformer/credentials_test.go (1)

48-64: 💤 Low value

Consider adding a test for all-empty OCICredentials.

The implementation returns nil, nil when all fields are empty (via if len(result) == 0). This edge case isn't explicitly covered. Optional addition:

func TestResolveCredentialsMap_OCICredentials_AllEmpty(t *testing.T) {
    resolver := &stubResolver{
        typed: &ocicredsv1.OCICredentials{},
    }

    creds, err := resolveCredentialsMap(t.Context(), resolver, runtime.Identity{"type": "OCIRegistry"})
    require.NoError(t, err)
    assert.Nil(t, creds, "all-empty credentials should return nil map")
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bindings/go/oci/transformer/credentials_test.go` around lines 48 - 64, Add a
unit test that verifies resolveCredentialsMap returns nil (not an empty map)
when OCICredentials has all empty fields: create a stubResolver with typed equal
to &ocicredsv1.OCICredentials{} and call resolveCredentialsMap(t.Context(),
resolver, runtime.Identity{"type":"OCIRegistry"}); assert no error and
assert.Nil on the returned creds. Name the test e.g.
TestResolveCredentialsMap_OCICredentials_AllEmpty and keep it alongside the
existing TestResolveCredentialsMap_OCICredentials_SkipsEmptyFields.
🤖 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/spec/identity/v1/register.go`:
- Around line 6-11: MustRegisterIdentityType is only used in tests and not
invoked during normal startup, so production schemes won't know
OCIRegistryIdentity; either add an init() that calls
MustRegisterIdentityType(scheme) on the global/runtime scheme used by the app,
or register the type during the package's initialization path used for other
bindings (similar to the credentials package). Locate the global/runtime scheme
initialization (or the package init functions that auto-register other types)
and call MustRegisterIdentityType there (or replace it by an init() in the same
package that registers &OCIRegistryIdentity{} with VersionedType and Type
aliases) so runtime resolution succeeds without test-only invocation.

---

Nitpick comments:
In `@bindings/go/oci/transformer/credentials_test.go`:
- Around line 48-64: Add a unit test that verifies resolveCredentialsMap returns
nil (not an empty map) when OCICredentials has all empty fields: create a
stubResolver with typed equal to &ocicredsv1.OCICredentials{} and call
resolveCredentialsMap(t.Context(), resolver,
runtime.Identity{"type":"OCIRegistry"}); assert no error and assert.Nil on the
returned creds. Name the test e.g.
TestResolveCredentialsMap_OCICredentials_AllEmpty and keep it alongside the
existing TestResolveCredentialsMap_OCICredentials_SkipsEmptyFields.
🪄 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: f7520074-0f81-4ed6-b8bf-2fd37df5bb93

📥 Commits

Reviewing files that changed from the base of the PR and between 94ab72f and b6fa258.

📒 Files selected for processing (16)
  • bindings/go/oci/repository/provider/provider.go
  • bindings/go/oci/repository/resource/resource_repository.go
  • bindings/go/oci/spec/credentials/v1/oci_credentials.go
  • bindings/go/oci/spec/credentials/v1/oci_credentials_test.go
  • bindings/go/oci/spec/identity/v1/oci_registry_identity.go
  • bindings/go/oci/spec/identity/v1/oci_registry_identity_test.go
  • bindings/go/oci/spec/identity/v1/register.go
  • bindings/go/oci/spec/identity/v1/schemas/OCIRegistryIdentity.schema.json
  • bindings/go/oci/spec/identity/v1/type.go
  • bindings/go/oci/spec/identity/v1/type_test.go
  • bindings/go/oci/spec/identity/v1/zz_generated.deepcopy.go
  • bindings/go/oci/spec/identity/v1/zz_generated.ocm_jsonschema.go
  • bindings/go/oci/spec/identity/v1/zz_generated.ocm_type.go
  • bindings/go/oci/transformer/add_oci_artifact_test.go
  • bindings/go/oci/transformer/credentials.go
  • bindings/go/oci/transformer/credentials_test.go
✅ Files skipped from review due to trivial changes (6)
  • bindings/go/oci/spec/identity/v1/schemas/OCIRegistryIdentity.schema.json
  • bindings/go/oci/spec/identity/v1/oci_registry_identity_test.go
  • bindings/go/oci/spec/identity/v1/zz_generated.ocm_jsonschema.go
  • bindings/go/oci/spec/identity/v1/zz_generated.ocm_type.go
  • bindings/go/oci/spec/identity/v1/zz_generated.deepcopy.go
  • bindings/go/oci/spec/credentials/v1/oci_credentials_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • bindings/go/oci/transformer/credentials.go
  • bindings/go/oci/spec/credentials/v1/oci_credentials.go

Comment thread bindings/go/oci/spec/identity/v1/register.go
Comment thread bindings/go/oci/transformer/credentials.go
@matthiasbruns matthiasbruns requested a review from Skarlso May 4, 2026 12:00
@matthiasbruns matthiasbruns enabled auto-merge (squash) May 4, 2026 13:18
@matthiasbruns matthiasbruns merged commit 26020bb into open-component-model:main May 4, 2026
36 checks passed
@matthiasbruns matthiasbruns deleted the feat/704_typed_credential_oci branch May 4, 2026 13:22
ocmbot2 Bot pushed a commit to morri-son/open-component-model that referenced this pull request May 4, 2026
…del#2360)

<!-- markdownlint-disable MD041 -->
#### What this PR does / why we need it
**Phase 2** typed oci bindings
[ADR](https://github.com/open-component-model/open-component-model/blob/main/docs/adr/0018_typed_credentials.md)

#### Which issue(s) this PR fixes
Contributes:
open-component-model/ocm-project#986

You can see the whole picture in
open-component-model#2148

#### Testing

##### How to test the changes

Unit & integration tests only.

I ran `task init/go.work` with the updated `credentials` binding to see
if the update breaks ocm - it does not :)

##### Verification

- [x] I have added/updated tests for my changes (see [Test
Requirements](../CONTRIBUTING.md#test-requirements))
- [x] Tests pass locally (`task test` and `task test/integration` if
applicable)
- [x] My changes do not decrease test coverage

---------

Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
Co-authored-by: DevBot <devbot@openclaw.ai> 26020bb
jakobmoellerdev pushed a commit that referenced this pull request May 12, 2026
On-behalf-of: SAP <matthias.bruns@sap.com>

<!-- markdownlint-disable MD041 -->
#### What this PR does / why we need it
Follow up of
#2360
after rolling back identity to `runtime.Identity`

- Updates internal `identity` usage to `OCIRegistryIdentity` where
sensible.
- Updates internal credential usage nearly everywhere, if it would not
just lead to a map->typed->map conversion chain

#### Which issue(s) this PR fixes
Contributes:
open-component-model/ocm-project#986

#### Breaking changes

- `bindings/go/oci/credentials/docker_config.go` `CredentialFunc` now
accepts typed identity and credentials (this shouldn't be exposed in the
first place imho)
- reverting ResolveTyped to use `runtime.Identity`

#### Testing

##### How to test the changes

I ran `task init/go.work` with the updated `credentials` binding to see
if the update breaks ocm - it does not :)

##### Verification

- [x] I have added/updated tests for my changes (see [Test
Requirements](../CONTRIBUTING.md#test-requirements))
- [x] Tests pass locally (`task test` and `task test/integration` if
applicable)
- [x] My changes do not decrease test coverage

---------

Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/documentation Documentation related kind/feature new feature, enhancement, improvement, extension size/l Large

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Update oci bindings to work with typed credentials

5 participants