Skip to content

feat: typed credentials for rsa binding (Phase 2)#2418

Merged
jakobmoellerdev merged 23 commits into
open-component-model:mainfrom
matthiasbruns:feat/988_typed_credential_rsa
May 7, 2026
Merged

feat: typed credentials for rsa binding (Phase 2)#2418
jakobmoellerdev merged 23 commits into
open-component-model:mainfrom
matthiasbruns:feat/988_typed_credential_rsa

Conversation

@matthiasbruns

@matthiasbruns matthiasbruns commented May 1, 2026

Copy link
Copy Markdown
Contributor

What this PR does / why we need it

Phase 2 typed signing bindings ADR

Which issue(s) this PR fixes

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

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

@matthiasbruns matthiasbruns requested a review from a team as a code owner May 1, 2026 10:13
@netlify

netlify Bot commented May 1, 2026

Copy link
Copy Markdown

Deploy Preview for ocm-website ready!

Name Link
🔨 Latest commit 7fb95d9
🔍 Latest deploy log https://app.netlify.com/projects/ocm-website/deploys/69fc8095de7df70008584021
😎 Deploy Preview https://deploy-preview-2418--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.

@github-actions github-actions Bot added the kind/feature new feature, enhancement, improvement, extension label May 1, 2026
@coderabbitai

coderabbitai Bot commented May 1, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9fcf49b4-732d-49d6-ac8e-06ad317ed208

📥 Commits

Reviewing files that changed from the base of the PR and between 4c0612a and 04e1ad5.

📒 Files selected for processing (3)
  • bindings/go/rsa/spec/credentials/v1/rsa_credentials.go
  • bindings/go/rsa/spec/credentials/v1/rsa_credentials_test.go
  • bindings/go/rsa/spec/credentials/v1/schemas/RSACredentials.schema.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • bindings/go/rsa/spec/credentials/v1/rsa_credentials_test.go

📝 Walkthrough

Walkthrough

The PR migrates the RSA signing/verification handler from untyped credential maps to strongly-typed RSACredentials and RSAIdentity structures. New credential and identity specs in bindings/go/rsa/spec/ define the typed shapes and registration logic; the handler and internal credentials code refactor to construct and use these typed values. All tests migrate to the public v1 API.

Changes

RSA Typed Credentials and Identities Migration

Layer / File(s) Summary
Type Definition & Registration
bindings/go/rsa/spec/credentials/v1/rsa_credentials.go, bindings/go/rsa/spec/identity/v1/type.go, bindings/go/rsa/spec/identity/v1/register.go
New RSACredentials struct with PEM/file fields and runtime.Type; new RSAIdentity struct with algorithm and signature fields. Constants define credential keys and identity attribute names. Registration functions wire types into a runtime.Scheme with versioned and unversioned aliases.
Autogenerated Accessors & Serialization
bindings/go/rsa/spec/credentials/v1/zz_generated.*.go, bindings/go/rsa/spec/identity/v1/zz_generated.*.go
Deepcopy, Type getter/setter, and JSONSchema methods auto-generated for both RSACredentials and RSAIdentity to enable runtime-compatible type handling and schema embedding.
JSON Schema Definitions
bindings/go/rsa/spec/credentials/v1/schemas/RSACredentials.schema.json, bindings/go/rsa/spec/identity/v1/schemas/RSAIdentity.schema.json
Schema documents define the structure and constraints for typed credentials/identities, including PEM field validation and legacy version support.
Internal Credentials Helpers
bindings/go/rsa/signing/handler/internal/credentials/credentials.go
Refactored to accept typed RSACredentials instead of maps; replaced internal constants with identityv1.V1Alpha1Type; added PublicKeyFromCredentials and CertificateChainFromCredentials helpers; simplified loadBytes to work without credential maps.
Signing Handler Core Logic
bindings/go/rsa/signing/handler/handler.go
Updated Sign and Verify paths to construct and use typed RSACredentials; added baseIdentity returning *identityv1.RSAIdentity and rsaIdentityToMap to convert typed identity to runtime map; aliased identity attribute constants to identityv1 package; refactored GetSigningCredentialConsumerIdentity and GetVerifyingCredentialConsumerIdentity to use typed identity model; updated classifyCredentialChain and verifyPEMSignature signatures to accept typed credentials.
Tests & Verification
bindings/go/rsa/signing/handler/handler_test.go, bindings/go/rsa/signing/handler/internal/credentials/credentials_test.go, bindings/go/rsa/spec/credentials/v1/rsa_credentials_test.go, bindings/go/rsa/spec/identity/v1/type_test.go
All tests migrated to use public v1 API; internal tests replaced with public credential key constants; added comprehensive credential/identity type behavior tests; added registration and scheme conversion tests to validate typed credential and identity handling.

Sequence Diagram

sequenceDiagram
    participant Caller
    participant Handler as RSA Handler
    participant Creds as RSACredentials<br/>(typed)
    participant Identity as RSAIdentity<br/>(typed)
    participant Runtime as Runtime Scheme
    participant KeyMgmt as Key Management

    Caller->>Handler: Sign(document, credentials map)
    Handler->>Creds: Load typed RSACredentials<br/>from map
    Handler->>Identity: Build RSAIdentity via<br/>baseIdentity(algorithm)
    Handler->>Identity: Set Signature field
    Handler->>Runtime: Convert RSAIdentity<br/>to runtime map via<br/>rsaIdentityToMap
    Handler->>KeyMgmt: PrivateKeyFromCredentials<br/>(typed creds)
    KeyMgmt-->>Handler: *rsa.PrivateKey
    Handler->>Handler: Sign document
    Handler-->>Caller: signature + identity

    Caller->>Handler: Verify(signature, identity map,<br/>credentials map)
    Handler->>Creds: Load typed RSACredentials<br/>from map
    Handler->>KeyMgmt: PublicKeyFromCredentials<br/>(typed creds)
    KeyMgmt-->>Handler: *rsapem.RSAPublicKeyPEM
    Handler->>Handler: Verify signature against<br/>public key
    Handler-->>Caller: valid/invalid result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • frewilhelm
  • fabianburth
  • Skarlso

🐰 From the rabbit's hutch:

Strong types emerge from the code's deep warren,
Credentials trade their map-based form for typed pattern—
RSA keys now dance in structs so fair,
Identity finds its schema, constant care.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 27.59% 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 clearly summarizes the main change: migrating RSA binding to use typed credentials as per Phase 2 of ADR 0018, which is the primary objective of this PR.
Description check ✅ Passed The description relates to the changeset by referencing Phase 2 of typed signing bindings ADR and issue #988, explaining testing approach, and confirming test coverage maintained.
Linked Issues check ✅ Passed The PR fulfills all key coding requirements from issue #988: introduces typed RSACredentials and RSAIdentity structs [new files], registers them via MustRegisterCredentialType/MustRegisterIdentityType, updates handler to use typed credentials API instead of raw maps, and adds comprehensive unit/integration tests for new typed credential functionality.
Out of Scope Changes check ✅ Passed All changes are scoped to implementing typed credentials for RSA binding per ADR 0018. No unrelated modifications detected; changes include new typed credential/identity packages, handler refactoring, test updates, and JSON schema definitions—all directly supporting the typed credentials objective.

✏️ 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 the size/m Medium label May 1, 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 (1)
bindings/go/rsa/signing/handler/handler.go (1)

28-29: ⚡ Quick win

Prefer identityv1 attribute-key constants to avoid key drift.

Now that this file imports identityv1, reusing identityv1.IdentityAttributeAlgorithm / identityv1.IdentityAttributeSignature would remove duplicate literals and keep identity key definitions centralized.

♻️ Proposed refactor
-const (
-	IdentityAttributeAlgorithm = "algorithm"
-	IdentityAttributeSignature = "signature"
-)
+// Use identityv1.IdentityAttributeAlgorithm and
+// identityv1.IdentityAttributeSignature directly.

@@
-	id[IdentityAttributeSignature] = name
+	id[identityv1.IdentityAttributeSignature] = name
@@
-	id[IdentityAttributeSignature] = signature.Name
+	id[identityv1.IdentityAttributeSignature] = signature.Name
@@
-	id := runtime.Identity{IdentityAttributeAlgorithm: string(algorithm)}
+	id := runtime.Identity{identityv1.IdentityAttributeAlgorithm: string(algorithm)}

Also applies to: 225-270, 405-409

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

In `@bindings/go/rsa/signing/handler/handler.go` around lines 28 - 29, This file
currently uses duplicate literal keys for identity attribute names; replace
those string literals with the centralized constants from the imported package
by using identityv1.IdentityAttributeAlgorithm and
identityv1.IdentityAttributeSignature wherever the algorithm/signature attribute
keys are referenced (e.g., in the functions and variables around the blocks
currently using literal keys at the top import area and the regions noted around
lines 225-270 and 405-409). Update any map lookups, assignments, and comparisons
that use the literal names to use these constants so the code references
identityv1.IdentityAttributeAlgorithm and identityv1.IdentityAttributeSignature
instead of hard-coded strings.
🤖 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/rsa/spec/credentials/v1/rsa_credentials_test.go`:
- Around line 13-18: Replace PEM-shaped fixture values and raw key-name literals
in the test's props map and other test cases with neutral placeholder strings
and the existing CredentialKey* constants: use CredentialKeyPublicKeyPEM,
CredentialKeyPublicKeyPEMFile, CredentialKeyPrivateKeyPEM, and
CredentialKeyPrivateKeyPEMFile as the map keys instead of raw literals, and set
their values to non-secret placeholders like "public-pem-placeholder",
"public-pem-file-placeholder", "private-pem-placeholder",
"private-pem-file-placeholder"; update all other occurrences in the same test
that currently use PEM-like strings or the hardcoded key names (the other props
usages) to follow the same pattern.

---

Nitpick comments:
In `@bindings/go/rsa/signing/handler/handler.go`:
- Around line 28-29: This file currently uses duplicate literal keys for
identity attribute names; replace those string literals with the centralized
constants from the imported package by using
identityv1.IdentityAttributeAlgorithm and identityv1.IdentityAttributeSignature
wherever the algorithm/signature attribute keys are referenced (e.g., in the
functions and variables around the blocks currently using literal keys at the
top import area and the regions noted around lines 225-270 and 405-409). Update
any map lookups, assignments, and comparisons that use the literal names to use
these constants so the code references identityv1.IdentityAttributeAlgorithm and
identityv1.IdentityAttributeSignature instead of hard-coded strings.
🪄 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: c81f1d6b-b1ff-4b0b-b8c5-7a10899fc06d

📥 Commits

Reviewing files that changed from the base of the PR and between ce7338d and 478f90c.

📒 Files selected for processing (11)
  • bindings/go/rsa/signing/handler/handler.go
  • bindings/go/rsa/signing/handler/internal/credentials/credentials.go
  • bindings/go/rsa/spec/credentials/v1/rsa_credentials.go
  • bindings/go/rsa/spec/credentials/v1/rsa_credentials_test.go
  • bindings/go/rsa/spec/credentials/v1/zz_generated.deepcopy.go
  • bindings/go/rsa/spec/credentials/v1/zz_generated.ocm_type.go
  • bindings/go/rsa/spec/identity/v1/register.go
  • bindings/go/rsa/spec/identity/v1/type.go
  • bindings/go/rsa/spec/identity/v1/type_test.go
  • bindings/go/rsa/spec/identity/v1/zz_generated.deepcopy.go
  • bindings/go/rsa/spec/identity/v1/zz_generated.ocm_type.go

Comment thread bindings/go/rsa/spec/credentials/v1/rsa_credentials_test.go Outdated
@matthiasbruns matthiasbruns force-pushed the feat/988_typed_credential_rsa branch 2 times, most recently from 8e08b13 to 036df9a Compare May 1, 2026 13:56

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

🧹 Nitpick comments (1)
bindings/go/rsa/signing/handler/handler.go (1)

405-409: ⚡ Quick win

Use the canonical RSA/v1 identity type here.

V1Alpha1Type is the deprecated alias. Emitting VersionedType from baseIdentity() keeps new requests on the canonical spec while preserving backward compatibility through the alias registration.

♻️ Proposed fix
 func baseIdentity(algorithm v1alpha1.SignatureAlgorithm) runtime.Identity {
 	id := runtime.Identity{IdentityAttributeAlgorithm: string(algorithm)}
-	id.SetType(identityv1.V1Alpha1Type)
+	id.SetType(identityv1.VersionedType)
 	return id
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bindings/go/rsa/signing/handler/handler.go` around lines 405 - 409, The
baseIdentity function currently sets the deprecated alias
identityv1.V1Alpha1Type; change it to emit the canonical RSA/v1 identity by
setting the identity type to identityv1.VersionedType in baseIdentity(algorithm
v1alpha1.SignatureAlgorithm) so new requests use the canonical spec while alias
registration (V1Alpha1Type) elsewhere preserves backward compatibility.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@bindings/go/rsa/signing/handler/handler.go`:
- Around line 405-409: The baseIdentity function currently sets the deprecated
alias identityv1.V1Alpha1Type; change it to emit the canonical RSA/v1 identity
by setting the identity type to identityv1.VersionedType in
baseIdentity(algorithm v1alpha1.SignatureAlgorithm) so new requests use the
canonical spec while alias registration (V1Alpha1Type) elsewhere preserves
backward compatibility.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 06227b58-273f-4341-a310-72f3d6bcdc68

📥 Commits

Reviewing files that changed from the base of the PR and between 478f90c and 036df9a.

📒 Files selected for processing (15)
  • bindings/go/rsa/signing/handler/handler.go
  • bindings/go/rsa/signing/handler/internal/credentials/credentials.go
  • bindings/go/rsa/spec/credentials/v1/rsa_credentials.go
  • bindings/go/rsa/spec/credentials/v1/rsa_credentials_test.go
  • bindings/go/rsa/spec/credentials/v1/schemas/RSACredentials.schema.json
  • bindings/go/rsa/spec/credentials/v1/zz_generated.deepcopy.go
  • bindings/go/rsa/spec/credentials/v1/zz_generated.ocm_jsonschema.go
  • bindings/go/rsa/spec/credentials/v1/zz_generated.ocm_type.go
  • bindings/go/rsa/spec/identity/v1/register.go
  • bindings/go/rsa/spec/identity/v1/schemas/RSAIdentity.schema.json
  • bindings/go/rsa/spec/identity/v1/type.go
  • bindings/go/rsa/spec/identity/v1/type_test.go
  • bindings/go/rsa/spec/identity/v1/zz_generated.deepcopy.go
  • bindings/go/rsa/spec/identity/v1/zz_generated.ocm_jsonschema.go
  • bindings/go/rsa/spec/identity/v1/zz_generated.ocm_type.go
✅ Files skipped from review due to trivial changes (6)
  • bindings/go/rsa/spec/credentials/v1/zz_generated.ocm_jsonschema.go
  • bindings/go/rsa/spec/identity/v1/zz_generated.ocm_type.go
  • bindings/go/rsa/spec/credentials/v1/schemas/RSACredentials.schema.json
  • bindings/go/rsa/spec/credentials/v1/zz_generated.deepcopy.go
  • bindings/go/rsa/spec/credentials/v1/zz_generated.ocm_type.go
  • bindings/go/rsa/spec/identity/v1/zz_generated.deepcopy.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • bindings/go/rsa/spec/identity/v1/register.go
  • bindings/go/rsa/signing/handler/internal/credentials/credentials.go
  • bindings/go/rsa/spec/credentials/v1/rsa_credentials.go

Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
On-behalf-of: SAP <matthias.bruns@sap.com>
Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
@matthiasbruns matthiasbruns force-pushed the feat/988_typed_credential_rsa branch from a616525 to 98c3607 Compare May 1, 2026 14:01
@matthiasbruns matthiasbruns changed the title feat: RSA typed credentials feat: RSA typed credentials (Phase 2) May 2, 2026
@matthiasbruns matthiasbruns changed the title feat: RSA typed credentials (Phase 2) feat: typed credentials for rsa binding (Phase 2) May 4, 2026
@matthiasbruns matthiasbruns changed the title feat: typed credentials for rsa binding (Phase 2) feat: typed credentials for signing binding (Phase 2) May 4, 2026
@matthiasbruns matthiasbruns marked this pull request as draft May 4, 2026 05:27
@matthiasbruns

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@matthiasbruns matthiasbruns changed the title feat: typed credentials for signing binding (Phase 2) feat: typed credentials for rsa binding (Phase 2) May 5, 2026
@github-actions github-actions Bot added area/documentation Documentation related size/l Large and removed size/m Medium area/documentation Documentation related labels May 5, 2026
On-behalf-of: SAP <matthias.bruns@sap.com>
Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
@matthiasbruns matthiasbruns force-pushed the feat/988_typed_credential_rsa branch from ba46bf2 to 5b3e727 Compare May 5, 2026 14:03
@github-actions github-actions Bot added the area/documentation Documentation related label May 5, 2026
matthiasbruns and others added 4 commits May 5, 2026 16:04
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 marked this pull request as ready for review May 5, 2026 14:50
Comment thread bindings/go/rsa/spec/credentials/v1/rsa_credentials.go Outdated
Comment thread docs/adr/0018_typed_credentials.md Outdated
matthiasbruns and others added 2 commits May 6, 2026 12:03
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: 2

Caution

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

⚠️ Outside diff range comments (1)
bindings/go/rsa/signing/handler/handler_test.go (1)

57-65: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Remove the shared rootPEM state from parallel subtests.

rootPEM is captured once for the whole alg subtest, but several cases mutate/read it while each case runs with t.Parallel(). That makes these cases race with each other and can verify against the wrong anchor path or a temp file owned by another subtest.

Minimal safe fix
 					for _, tt := range tests {
 						t.Run(tt.name, func(t *testing.T) {
-							t.Parallel()
 							sig := tt.build(t)
 							err := h.Verify(t.Context(), sig, nil, tt.creds(t))
 							if tt.wantErr == "" {
 								require.NoError(t, err)
 								return

Also applies to: 508-519

🤖 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/rsa/signing/handler/handler_test.go` around lines 57 - 65, The
shared variable rootPEM is causing data races between parallel subtests (the
outer alg subtest and inner t.Parallel() cases); remove the shared state by
making rootPEM local to each parallel case — e.g. move rootPEM creation into the
tc.build or tc.creds functions (or return it from build) so each test case gets
its own independent rootPEM, and update references in the test cases and any
helper functions to use the per-case value instead of the package-scoped
rootPEM.
🧹 Nitpick comments (1)
bindings/go/rsa/signing/handler/handler.go (1)

422-431: 💤 Low value

Consider conditional assignment in rsaIdentityToMap only if identity-graph matching requires absent keys rather than empty values.

The function unconditionally populates IdentityAttributeAlgorithm and IdentityAttributeSignature even when the corresponding fields are empty strings. The typed RSAIdentity uses omitempty JSON tags, creating a semantic mismatch: the typed representation omits empty fields, while the map always includes them. This could theoretically cause identity matching to fail if consumers expect the absence of a key rather than an empty string value.

However, the test suite explicitly validates that both keys are always present in the resulting map (e.g., require.Equal(t, alg, id[identityv1.IdentityAttributeAlgorithm])). Applying the proposed conditional-assignment refactor would require updating all identity assertions. Only pursue this if you confirm that identity-graph matching actually fails with the current unconditional behavior, or if the code path documents that empty values must be omitted to match the typed representation's semantics.

🤖 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/rsa/signing/handler/handler.go` around lines 422 - 431, The
rsaIdentityToMap function currently always sets
identityv1.IdentityAttributeAlgorithm and identityv1.IdentityAttributeSignature
to potentially-empty strings, which can differ from the typed RSAIdentity
omitempty semantics; change rsaIdentityToMap (in handler.go) to only set
m[identityv1.IdentityAttributeAlgorithm] = id.Algorithm and
m[identityv1.IdentityAttributeSignature] = id.Signature when id.Algorithm and
id.Signature are non-empty (e.g., check id.Algorithm != "" and id.Signature !=
"") so absent fields are truly omitted from the returned runtime.Identity map;
if you make this change, run/update tests that assert keys exist (they reference
rsaIdentityToMap outputs) to reflect the new omission behavior.
🤖 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/rsa/signing/handler/internal/credentials/credentials.go`:
- Around line 51-56: CertificateChainFromCredentials currently swallows
loadBytes errors and returns (nil, nil); change it so any error from loadBytes
is propagated: call loadBytes(creds.PublicKeyPEM, creds.PublicKeyPEMFile), if
err != nil return nil, err, and only if err == nil and len(b) == 0 return nil,
nil; then continue to call rsapem.ParseCertificateChain(b) and return its
result. This ensures failures reading PublicKeyPEMFile (or other IO errors) are
not treated as "no chain configured" — update the function
CertificateChainFromCredentials and keep references to loadBytes,
creds.PublicKeyPEM, and creds.PublicKeyPEMFile.

In `@bindings/go/rsa/spec/credentials/v1/schemas/RSACredentials.schema.json`:
- Around line 34-37: The schema currently only requires "type" so an empty
RSACredentials object is considered valid; update the RSACredentials schema by
adding an "anyOf" constraint that requires at least one key-material property
(e.g., require one of "privateKeyPem", "publicKeyPem", "privateKeyJwk",
"publicKeyJwk" — or whatever key names your template uses) so validation fails
when no usable key is present; keep "additionalProperties": false and ensure the
new "anyOf" entries reference the exact property names used in the schema (e.g.,
the RSACredentials schema object where "required": ["type"] is defined).

---

Outside diff comments:
In `@bindings/go/rsa/signing/handler/handler_test.go`:
- Around line 57-65: The shared variable rootPEM is causing data races between
parallel subtests (the outer alg subtest and inner t.Parallel() cases); remove
the shared state by making rootPEM local to each parallel case — e.g. move
rootPEM creation into the tc.build or tc.creds functions (or return it from
build) so each test case gets its own independent rootPEM, and update references
in the test cases and any helper functions to use the per-case value instead of
the package-scoped rootPEM.

---

Nitpick comments:
In `@bindings/go/rsa/signing/handler/handler.go`:
- Around line 422-431: The rsaIdentityToMap function currently always sets
identityv1.IdentityAttributeAlgorithm and identityv1.IdentityAttributeSignature
to potentially-empty strings, which can differ from the typed RSAIdentity
omitempty semantics; change rsaIdentityToMap (in handler.go) to only set
m[identityv1.IdentityAttributeAlgorithm] = id.Algorithm and
m[identityv1.IdentityAttributeSignature] = id.Signature when id.Algorithm and
id.Signature are non-empty (e.g., check id.Algorithm != "" and id.Signature !=
"") so absent fields are truly omitted from the returned runtime.Identity map;
if you make this change, run/update tests that assert keys exist (they reference
rsaIdentityToMap outputs) to reflect the new omission behavior.
🪄 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: 3a6fdfd0-8d21-4d05-bf29-23eeabb4a2e1

📥 Commits

Reviewing files that changed from the base of the PR and between 036df9a and 4c0612a.

📒 Files selected for processing (18)
  • bindings/go/rsa/signing/handler/handler.go
  • bindings/go/rsa/signing/handler/handler_test.go
  • bindings/go/rsa/signing/handler/internal/credentials/credentials.go
  • bindings/go/rsa/signing/handler/internal/credentials/credentials_test.go
  • bindings/go/rsa/spec/credentials/v1/rsa_credentials.go
  • bindings/go/rsa/spec/credentials/v1/rsa_credentials_test.go
  • bindings/go/rsa/spec/credentials/v1/schemas/RSACredentials.schema.json
  • bindings/go/rsa/spec/credentials/v1/zz_generated.deepcopy.go
  • bindings/go/rsa/spec/credentials/v1/zz_generated.ocm_jsonschema.go
  • bindings/go/rsa/spec/credentials/v1/zz_generated.ocm_type.go
  • bindings/go/rsa/spec/identity/v1/register.go
  • bindings/go/rsa/spec/identity/v1/schemas/RSAIdentity.schema.json
  • bindings/go/rsa/spec/identity/v1/type.go
  • bindings/go/rsa/spec/identity/v1/type_test.go
  • bindings/go/rsa/spec/identity/v1/zz_generated.deepcopy.go
  • bindings/go/rsa/spec/identity/v1/zz_generated.ocm_jsonschema.go
  • bindings/go/rsa/spec/identity/v1/zz_generated.ocm_type.go
  • docs/adr/0018_typed_credentials.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • bindings/go/rsa/spec/identity/v1/zz_generated.ocm_jsonschema.go

Comment thread bindings/go/rsa/signing/handler/internal/credentials/credentials.go
matthiasbruns and others added 4 commits May 6, 2026 12:19
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>

@jakobmoellerdev jakobmoellerdev left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this is lgtm to me. only think im wondering is if the keys should change but there I need some more context. apart from this, great change, very focused!

Comment thread bindings/go/rsa/spec/credentials/v1/rsa_credentials.go
@jakobmoellerdev jakobmoellerdev merged commit aa73e6e into open-component-model:main May 7, 2026
22 checks passed
@matthiasbruns matthiasbruns deleted the feat/988_typed_credential_rsa branch May 7, 2026 16:44
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 rsa bindings to work with typed credentials

3 participants