Skip to content

feat!: credentials phase 3 - credential bindings#2518

Merged
matthiasbruns merged 15 commits into
open-component-model:mainfrom
matthiasbruns:feat/1047_typed_credentials_phase_3_credentials
May 19, 2026
Merged

feat!: credentials phase 3 - credential bindings#2518
matthiasbruns merged 15 commits into
open-component-model:mainfrom
matthiasbruns:feat/1047_typed_credentials_phase_3_credentials

Conversation

@matthiasbruns

@matthiasbruns matthiasbruns commented May 15, 2026

Copy link
Copy Markdown
Contributor

What this PR does / why we need it

Phase 3 of the credential migration

This PR updated the credential bindings.

This PR adds typed support to both CredentialPlugin and RepositoryPlugin as defined in the ADR

Additionally, we also replace the deprecated Resolve methods from the interfaces, as well as from the credentials.

You can see the full impact in #2517

Which issue(s) this PR fixes

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

On-behalf-of: SAP <matthias.bruns@sap.com>
Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
@netlify

netlify Bot commented May 15, 2026

Copy link
Copy Markdown

Deploy Preview for ocm-website ready!

Name Link
🔨 Latest commit 14404d9
🔍 Latest deploy log https://app.netlify.com/projects/ocm-website/deploys/6a0c219a5a377d0008eb00e9
😎 Deploy Preview https://deploy-preview-2518--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 May 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR removes map-based Resolve APIs and migrates the credentials stack to runtime.Typed: interfaces (Resolver, RepositoryPlugin, CredentialPlugin), Graph, direct/indirect/static resolvers, merging/caching, tests, and benchmarks now use ResolveTyped end-to-end.

Changes

Credential Resolution API Standardization

Layer / File(s) Summary
Public interface contract removal
bindings/go/credentials/interface.go, bindings/go/credentials/plugins.go
Removed deprecated map-based Resolve methods; public contracts now expose only ResolveTyped using runtime.Typed.
Graph public API and documentation
bindings/go/credentials/graph.go, bindings/go/credentials/doc.go
Removed Graph.Resolve; docs and examples updated to reference and use Graph.ResolveTyped as the primary entrypoint and adjusted thread-safety wording.
Direct graph-based resolution
bindings/go/credentials/resolve_direct.go
resolveFromGraph now traverses edges and calls plugin.ResolveTyped, accumulates runtime.Typed results, merges with mergeTyped into *v1.DirectCredentials, caches, and returns typed credentials; removed typed-to-map bridging logic.
Direct resolution tests
bindings/go/credentials/resolve_direct_test.go
Replaced typed-to-map tests with mergeTyped suite; added helmHTTPCredentials test type, newSchemeWith helper, and tests for empty, passthrough, merge, override, and failure cases.
Indirect repository-based resolution
bindings/go/credentials/resolve_indirect.go
Repository resolution now operates end-to-end on runtime.Typed, calls plugin.ResolveTyped, and caches/returns typed results directly without wrapping into v1.DirectCredentials.
Static credential resolver & tests
bindings/go/credentials/resolve_static.go, bindings/go/credentials/resolve_static_test.go
Removed StaticCredentialsResolver.Resolve; tests updated to call ResolveTyped, cast to *v1.DirectCredentials, and assert Properties, preserving concurrency and cloning checks.
Graph tests and benchmarks
bindings/go/credentials/graph_test.go, bindings/go/credentials/graph_bench_test.go
Mocks and benchmarks updated to use ResolveTyped signatures and runtime.Typed results; tests assert typed values (often *v1.DirectCredentials) and error cases updated to ResolveTyped.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Graph
  participant CredentialPlugin
  participant RepositoryPlugin
  participant Cache
  Client->>Graph: ResolveTyped(ctx, identity)
  alt cached
    Graph->>Cache: getCredentials(node)
    Cache-->>Graph: runtime.Typed
  else not cached
    Graph->>CredentialPlugin: ResolveTyped(ctx, identity, nil)
    Graph->>RepositoryPlugin: ResolveTyped(ctx, cfg, identity, nil)
    CredentialPlugin-->>Graph: runtime.Typed
    RepositoryPlugin-->>Graph: runtime.Typed
    Graph->>Graph: mergeTyped(runtime.Typed...)
    Graph->>Cache: setCredentials(node, merged)
  end
  Graph-->>Client: runtime.Typed (often *v1.DirectCredentials)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • frewilhelm
  • fabianburth
  • jakobmoellerdev

Poem

🐰 I hopped through code with nimble feet,

Maps gave way to types so neat.
ResolveTyped now leads the chore,
Merged creds safe forevermore.
Carrots for reviewers — sweet!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% 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!: credentials phase 3 - credential bindings' clearly identifies the main change as implementing phase 3 of the credential migration for the credential bindings, with the breaking change indicator (!) appropriately signaling removal of deprecated methods.
Linked Issues check ✅ Passed All primary scope items from issue #1047 are implemented: CredentialPlugin and RepositoryPlugin interfaces now have ResolveTyped methods, deprecated Resolve methods removed, graph caller updated for typed resolution, and comprehensive test updates confirm the changes.
Out of Scope Changes check ✅ Passed All changes are within scope of phase 3: credential interfaces (plugins.go, interface.go), credential graph implementations (resolve_direct.go, resolve_indirect.go, resolve_static.go), and comprehensive test coverage for the new typed resolution pattern.
Description check ✅ Passed The PR description clearly relates to the changeset: it describes Phase 3 of credential migration, updating credential bindings with typed support for CredentialPlugin and RepositoryPlugin, removing deprecated Resolve methods, and references the relevant ADR and issue.

✏️ 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.

@matthiasbruns matthiasbruns changed the title chore: credentials phase 3 chore: credentials phase 3 - credential bindings May 15, 2026
@github-actions github-actions Bot added kind/chore chore, maintenance, etc. size/m Medium labels May 15, 2026
@matthiasbruns matthiasbruns changed the title chore: credentials phase 3 - credential bindings fear: credentials phase 3 - credential bindings May 15, 2026
@matthiasbruns matthiasbruns changed the title fear: credentials phase 3 - credential bindings feat: credentials phase 3 - credential bindings May 15, 2026
@matthiasbruns matthiasbruns changed the title feat: credentials phase 3 - credential bindings feat!: credentials phase 3 - credential bindings May 15, 2026
@github-actions github-actions Bot added kind/feature new feature, enhancement, improvement, extension !BREAKING-CHANGE! Breaking change in API or ocm-cli or spec labels May 15, 2026
@matthiasbruns matthiasbruns marked this pull request as ready for review May 15, 2026 08:40
@matthiasbruns matthiasbruns requested a review from a team as a code owner May 15, 2026 08:40

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
bindings/go/credentials/graph_test.go (1)

612-642: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Test case does not validate credential resolution result.

The test case "recursive resolution through multiple edges leads to successful merged resolution" (lines 612-642) validates that the graph can be constructed without errors, but it does not actually call ResolveTyped to verify the resolved credentials. Given the new "last writer wins" behavior in resolve_direct.go, this test should validate the actual resolution result.

🧪 Add resolution validation to the test

After line 651, add resolution and validation:

 		} else {
 			r.NoError(err, "Failed to get graph")
+			// Validate resolution behavior with multiple edges
+			typed, err := graph.ResolveTyped(t.Context(), runtime.Identity{
+				"type": "RecursionTest",
+				"path": "recursive/path/abc",
+			})
+			r.NoError(err)
+			dc, ok := typed.(*v1.DirectCredentials)
+			r.True(ok, "expected *v1.DirectCredentials")
+			// Verify last-writer-wins: only credentials from path/b edge should be present
+			r.Equal("def", dc.Properties["password"])
 		}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@bindings/go/credentials/graph_test.go` around lines 612 - 642, The test
"recursive resolution through multiple edges leads to successful merged
resolution" currently only builds the graph; update it to actually call
ResolveTyped (the resolver used in resolve_direct.go) for the consumer with
identity type RecursionTest/path "recursive/path/abc" and assert the merged
credential fields match the new "last writer wins" semantics (expect username
"abc" and password "def"). Locate the test case in graph_test.go, invoke
ResolveTyped or the package's ResolveTyped helper for that identity, and add
assertions that the resolved credential map or struct contains username == "abc"
and password == "def" (or equivalent keys/types used by ResolveTyped) to
validate the resolution result.
🧹 Nitpick comments (1)
bindings/go/credentials/resolve_direct.go (1)

51-53: 🏗️ Heavy lift

Add test coverage validating "last writer wins" behavior with multiple credential edges.

The comment correctly identifies that typed credentials cannot be merged generically—only the last resolved credential is retained, unlike the previous map-based implementation. However, the existing test "recursive resolution through multiple edges leads to successful merged resolution" (graph_test.go) only validates that the graph construction succeeds; it does not assert what credentials are actually returned when a consumer has multiple edges. This test should be expanded or a new test added to explicitly verify that only the last edge's credentials are present in the final resolution result, not a merge of all edges.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@bindings/go/credentials/resolve_direct.go` around lines 51 - 53, Expand or
add a unit test in graph_test.go to assert "last writer wins" when resolving
typed credentials: create a consumer node with multiple incoming credential
edges each supplying distinct credential values, invoke the same resolution path
used in the existing test (the code path that sets resolved = credentials in
resolve_direct.go), and assert that the returned resolved value equals the
credential from the last edge only (not a merge). Reference the resolution code
by the resolved variable assignment in resolve_direct.go and the existing test
"recursive resolution through multiple edges leads to successful merged
resolution" to locate where to augment or add the new assertion.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@bindings/go/credentials/graph_test.go`:
- Around line 612-642: The test "recursive resolution through multiple edges
leads to successful merged resolution" currently only builds the graph; update
it to actually call ResolveTyped (the resolver used in resolve_direct.go) for
the consumer with identity type RecursionTest/path "recursive/path/abc" and
assert the merged credential fields match the new "last writer wins" semantics
(expect username "abc" and password "def"). Locate the test case in
graph_test.go, invoke ResolveTyped or the package's ResolveTyped helper for that
identity, and add assertions that the resolved credential map or struct contains
username == "abc" and password == "def" (or equivalent keys/types used by
ResolveTyped) to validate the resolution result.

---

Nitpick comments:
In `@bindings/go/credentials/resolve_direct.go`:
- Around line 51-53: Expand or add a unit test in graph_test.go to assert "last
writer wins" when resolving typed credentials: create a consumer node with
multiple incoming credential edges each supplying distinct credential values,
invoke the same resolution path used in the existing test (the code path that
sets resolved = credentials in resolve_direct.go), and assert that the returned
resolved value equals the credential from the last edge only (not a merge).
Reference the resolution code by the resolved variable assignment in
resolve_direct.go and the existing test "recursive resolution through multiple
edges leads to successful merged resolution" to locate where to augment or add
the new assertion.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3659d237-1a0b-4b50-8f77-a1df4ed728ff

📥 Commits

Reviewing files that changed from the base of the PR and between 6a25d53 and 443008d.

📒 Files selected for processing (11)
  • bindings/go/credentials/doc.go
  • bindings/go/credentials/graph.go
  • bindings/go/credentials/graph_bench_test.go
  • bindings/go/credentials/graph_test.go
  • bindings/go/credentials/interface.go
  • bindings/go/credentials/plugins.go
  • bindings/go/credentials/resolve_direct.go
  • bindings/go/credentials/resolve_direct_test.go
  • bindings/go/credentials/resolve_indirect.go
  • bindings/go/credentials/resolve_static.go
  • bindings/go/credentials/resolve_static_test.go
💤 Files with no reviewable changes (4)
  • bindings/go/credentials/graph.go
  • bindings/go/credentials/resolve_direct_test.go
  • bindings/go/credentials/interface.go
  • bindings/go/credentials/resolve_static.go

Comment thread bindings/go/credentials/resolve_direct.go
@github-actions github-actions Bot added size/l Large and removed size/m Medium labels May 15, 2026
On-behalf-of: SAP <matthias.bruns@sap.com>
Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
@matthiasbruns matthiasbruns force-pushed the feat/1047_typed_credentials_phase_3_credentials branch from 7ea6255 to 9837f0e Compare May 15, 2026 09:30
Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
@matthiasbruns matthiasbruns force-pushed the feat/1047_typed_credentials_phase_3_credentials branch from 2e651f3 to 4e10530 Compare May 15, 2026 09:33

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@bindings/go/credentials/resolve_direct.go`:
- Around line 86-110: mergeTyped treats DirectCredentials and other typed
credentials differently: DirectCredentials copies dc.Properties verbatim (so
empty strings override), while the non-DC branch only copies non-empty strings
and drops non-string fields. In mergeTyped, change the non-DC branch (the block
that converts to runtime.Raw, unmarshals into fields, and iterates for k,v) to
stop requiring v be a non-empty string; instead convert any non-nil v to a
string (e.g. via fmt.Sprint or equivalent) and assign merged[k] = that string
(skip the "type" key as before), allowing empty strings to override earlier
values and preserving override semantics consistent with DirectCredentials; keep
scheme.Convert, json.Unmarshal, raw, and fields logic intact.
🪄 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: 5725313f-b47c-45d4-8601-e5b8e47f2eaf

📥 Commits

Reviewing files that changed from the base of the PR and between 443008d and 1e219e6.

📒 Files selected for processing (2)
  • bindings/go/credentials/resolve_direct.go
  • bindings/go/credentials/resolve_direct_test.go

Comment thread bindings/go/credentials/resolve_direct.go
On-behalf-of: SAP <matthias.bruns@sap.com>
Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
…hub.com:matthiasbruns/open-component-model into feat/1047_typed_credentials_phase_3_credentials

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@bindings/go/credentials/resolve_direct.go`:
- Around line 27-32: The cache key is inconsistent: g.getCredentials(vertex.ID)
is used for lookup but the result is stored under node := identity.String(); fix
by using the same key for both operations—either change the lookup to
g.getCredentials(identity.String()) or change the stored key to vertex.ID—so
that the cache reads and writes use the identical key (update the code paths
around g.getCredentials, vertex.ID, identity.String(), and the assignment to
node in resolve_direct.go to match resolve_indirect.go's approach).
🪄 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: 60c1caf9-0854-48b5-b787-f9e689164e4f

📥 Commits

Reviewing files that changed from the base of the PR and between 1e219e6 and 15a4adc.

📒 Files selected for processing (1)
  • bindings/go/credentials/resolve_direct.go

Comment thread bindings/go/credentials/resolve_direct.go
On-behalf-of: SAP <matthias.bruns@sap.com>
Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
@matthiasbruns matthiasbruns force-pushed the feat/1047_typed_credentials_phase_3_credentials branch from 2b2c0c9 to 6c87f61 Compare May 18, 2026 13:41
Comment thread bindings/go/credentials/plugins.go Outdated
Comment thread bindings/go/credentials/resolve_direct.go
matthiasbruns and others added 2 commits May 19, 2026 09:47
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>
@matthiasbruns matthiasbruns enabled auto-merge (squash) May 19, 2026 08:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

!BREAKING-CHANGE! Breaking change in API or ocm-cli or spec kind/chore chore, maintenance, etc. kind/feature new feature, enhancement, improvement, extension size/l Large

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants