You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The goal is to lay the foundation so that bindings can gradually migrate to typed credentials without any downstream breakage.
Problem
Most credentials can be fairly complex. OCIRegistry for example has several fields. These fields in OCM today are undocumented. Because they are undocumented they are hard to use.
Credentials are map[string]string — key names like username, password, accessToken are scattered string constants with no compile-time guarantees. A real bug exists where OCI resource downloads used access_token (snake_case) while docker config resolution used accessToken (camelCase), causing silent auth failures (ocm-project#985).
Consumer identity types are scattered strings — "OCIRegistry", "HelmChartRepository", "RSA/v1alpha1" defined independently per binding with no central registry and no way to validate identity ↔ credential compatibility.
Scope — Phase 1: Foundation
Add the foundational types and interfaces that enable typed credentials. No existing behavior changes, no downstream breakage — all existing code continues to work.
Specifically:
Add ResolveTyped method to the existing Resolver interface — returns runtime.Typed instead of map[string]string. Adding a method to an interface breaks implementors (all in our codebase), not consumers. Each binding migrates from Resolve to ResolveTyped independently in later phases.
Add CredentialTypeSchemeProvider and IdentityTypeSchemeProvider interfaces to the credential graph — two optional scheme providers passed via graph configuration (Options). The graph stores credentials as runtime.Typed internally and resolves typed credentials from config when a provider is configured. Both providers are nil-safe — the graph degrades to DirectCredentials behavior when no provider is configured.
Add CredentialAcceptor interface to runtime — typed identity structs declare which credential types they accept. The graph validates during ingestion that configured credential types are compatible (warnings, not errors — plugins loaded after ingestion may introduce unknown types).
sequenceDiagram
participant C as Consumer (e.g. Helm downloader)
participant I as Typed Identity (HelmChartRepositoryIdentity)
participant G as Credential Graph
participant S as CredentialTypeSchemeProvider
C->>I: construct typed identity
I-->>C: .Identity() → runtime.Identity
C->>G: ResolveTyped(identity)
G->>G: match identity in DAG
G->>G: resolve raw credential from config
G->>S: Scheme() → convert to runtime.Typed
S-->>G: typed credential
G-->>C: HelmHTTPCredentials
C->>C: type-assert fields (CertFile, KeyFile, Keyring)
Loading
Note that previous credentials of type Properties still work — DirectCredentials/v1 is the fallback. Consumers only switch to ResolveTyped when they are ready (Phase 2+).
Out of Scope
Binding migration to typed credentials (Phase 2 — separate issues per binding)
Plugin interface changes (Phase 3)
Repository interface changes (Phase 4)
Consumer migration (Phase 5)
Legacy cleanup / deprecation of Resolve (Phase 6)
Done Criteria
ResolveTyped method added to Resolver interface
CredentialTypeSchemeProvider and IdentityTypeSchemeProvider interfaces accepted by credential graph via Options
CredentialAcceptor interface added to runtime
DirectCredentials/v1 registered as universal fallback
Graph degrades gracefully when no scheme providers are configured (nil-safe)
Existing .ocmconfig files continue to work unchanged
Code has been reviewed by other team members
Analysis of existing tests (Unit and Integration)
Unit Tests created for new code or existing Unit Tests updated
Integration Test Suite updated (includes deletion of existing unnecessary Integration Test and/or creation of new ones if required)
Description
This issue covers Phase 1 (Foundation) of the typed credentials work described in ADR 0017 — Typed Credentials and Consumer Identity Types.
The goal is to lay the foundation so that bindings can gradually migrate to typed credentials without any downstream breakage.
Problem
Most credentials can be fairly complex.
OCIRegistryfor example has several fields. These fields in OCM today are undocumented. Because they are undocumented they are hard to use.Credentials are
map[string]string— key names likeusername,password,accessTokenare scattered string constants with no compile-time guarantees. A real bug exists where OCI resource downloads usedaccess_token(snake_case) while docker config resolution usedaccessToken(camelCase), causing silent auth failures (ocm-project#985).Consumer identity types are scattered strings —
"OCIRegistry","HelmChartRepository","RSA/v1alpha1"defined independently per binding with no central registry and no way to validate identity ↔ credential compatibility.Scope — Phase 1: Foundation
Add the foundational types and interfaces that enable typed credentials. No existing behavior changes, no downstream breakage — all existing code continues to work.
Specifically:
Add
ResolveTypedmethod to the existingResolverinterface — returnsruntime.Typedinstead ofmap[string]string. Adding a method to an interface breaks implementors (all in our codebase), not consumers. Each binding migrates fromResolvetoResolveTypedindependently in later phases.Add
CredentialTypeSchemeProviderandIdentityTypeSchemeProviderinterfaces to the credential graph — two optional scheme providers passed via graph configuration (Options). The graph stores credentials asruntime.Typedinternally and resolves typed credentials from config when a provider is configured. Both providers are nil-safe — the graph degrades toDirectCredentialsbehavior when no provider is configured.CredentialAcceptorinterface to runtime — typed identity structs declare which credential types they accept. The graph validates during ingestion that configured credential types are compatible (warnings, not errors — plugins loaded after ingestion may introduce unknown types).DirectCredentials/v1as the universal fallback — ensures.ocmconfigfiles withCredentials/v1andpropertiescontinue to work unchanged.Where before the flow was:
sequenceDiagram participant Runtime participant Graph participant Plugin Runtime->>Plugin: getConsumerIdentity() Plugin->>Runtime: runtime.Identity Runtime->>Graph: Resolve(runtime.Identity) Graph->>Runtime: map[string]string Runtime->>Plugin: Function(e.g. Get CV): function(..., credentials map[string]string)after Phase 1 the graph additionally supports:
sequenceDiagram participant C as Consumer (e.g. Helm downloader) participant I as Typed Identity (HelmChartRepositoryIdentity) participant G as Credential Graph participant S as CredentialTypeSchemeProvider C->>I: construct typed identity I-->>C: .Identity() → runtime.Identity C->>G: ResolveTyped(identity) G->>G: match identity in DAG G->>G: resolve raw credential from config G->>S: Scheme() → convert to runtime.Typed S-->>G: typed credential G-->>C: HelmHTTPCredentials C->>C: type-assert fields (CertFile, KeyFile, Keyring)Note that previous credentials of type Properties still work —
DirectCredentials/v1is the fallback. Consumers only switch toResolveTypedwhen they are ready (Phase 2+).Out of Scope
Resolve(Phase 6)Done Criteria
ResolveTypedmethod added toResolverinterfaceCredentialTypeSchemeProviderandIdentityTypeSchemeProviderinterfaces accepted by credential graph viaOptionsCredentialAcceptorinterface added to runtimeDirectCredentials/v1registered as universal fallback.ocmconfigfiles continue to work unchanged