Configure Registry Credentials

Goal

Configure OCM to authenticate against multiple OCI registries — pinning explicit credentials for specific registries while using Docker config as a catch-all fallback.

You’ll end up with

  • An OCM config file that resolves credentials automatically for every ocm command
  • Explicit control over specific registry paths with Docker config covering the rest

Prerequisites

  • OCM CLI installed
  • Docker CLI installed and docker login run for any registries you want as fallback (creates ~/.docker/config.json)

Steps

  1. Identity by hostname only

    Create $HOME/.ocmconfig with an identity that matches any path on a hostname:

    type: generic.config.ocm.software/v1
    configurations:
      - type: credentials.config.ocm.software
        consumers:
          # Hostname-only identity
          - identities:
              - type: OCIRegistry
                hostname: ghcr.io  # No path = matches all paths
            credentials:
              - type: OCICredentials/v1
                username: my-user
                password: ghp_your_token_here

    Identity: hostname: ghcr.io (no path)
    Matches: ghcr.io/any-org/any-repo, ghcr.io/foo/bar, etc. — all paths on this hostname.

  2. Identity by hostname + exact path

    Add an identity that matches a specific path on a hostname:

    type: generic.config.ocm.software/v1
    configurations:
      - type: credentials.config.ocm.software
        consumers:
          # ... other consumers
          # Hostname + exact path identity
          - identities:
              - type: OCIRegistry
                hostname: ghcr.io
                path: my-org/production  # Exact path match
            credentials:
              - type: OCICredentials/v1
                username: prod-user
                password: ghp_production_token

    Identity: hostname: ghcr.io + path: my-org/production
    Matches: Only ghcr.io/my-org/production (exact match)
    Differs from step 1: The first consumer now matches only one specific path. The second consumer (hostname-only) catches everything else on ghcr.io.

  3. Identity by hostname + path pattern

    Add an identity that matches multiple paths using a glob pattern:

    type: generic.config.ocm.software/v1
    configurations:
      - type: credentials.config.ocm.software
        consumers:
          # ... other consumers
          # Hostname + path glob identity
          - identities:
              - type: OCIRegistry
                hostname: ghcr.io
                path: my-org/*  # Glob — matches one segment after my-org/
            credentials:
              - type: OCICredentials/v1
                username: org-user
                password: ghp_org_token

    Identity: hostname: ghcr.io + path: my-org/*
    Matches: ghcr.io/my-org/staging, ghcr.io/my-org/dev, etc. — any single segment after my-org/
    Differs from step 2: Uses a glob pattern (*) instead of an exact path. More specific identities (like path: my-org/production) are checked first.

  4. Identity via Docker config (fallback)

    Add a repositories section to use Docker config for any registry not matched by consumers:

    type: generic.config.ocm.software/v1
    configurations:
      - type: credentials.config.ocm.software
        consumers:
        # ... other consumers
        # Docker config fallback
        repositories:
          - repository:
              type: DockerConfig/v1
              dockerConfigFile: "~/.docker/config.json"  # Fallback for unmatched registries

    Identity: Derived from the auths section in Docker config file (~/.docker/config.json)
    Matches: Any registry with credentials in Docker config that wasn’t matched by a consumer
    Differs from steps 1-3: This is a repository (not a consumer). OCM checks all consumers first, then falls back to repositories. Use this for registries you authenticate with docker login.

  5. Verify credentials resolve

    Config alone does not prove authentication works. Run any read-only command that touches a protected registry and watch it succeed. get cv resolves credentials, authenticates, and lists the component version without changing anything:

    ocm get cv ghcr.io/my-org/production//ocm.software/examples/demo:1.0.0

    To see how credentials were resolved, raise the log level:

    ocm --loglevel debug get cv ghcr.io/my-org/production//ocm.software/examples/demo:1.0.0

    A successful listing confirms the identity matched and the credentials were accepted by the registry. A 401 Unauthorized points at a mismatched identity or wrong credentials, see Troubleshooting below.

Complete Example Configuration

Here’s a complete configuration combining all identity types:

type: generic.config.ocm.software/v1
configurations:
  - type: credentials.config.ocm.software
    consumers:
      # Path glob: matches ghcr.io/my-org/staging, ghcr.io/my-org/dev, etc.
      - identities:
          - type: OCIRegistry
            hostname: ghcr.io
            path: my-org/*
        credentials:
          - type: OCICredentials/v1
            username: org-user
            password: ghp_org_token
      # Exact path: matches only ghcr.io/my-org/production (takes precedence over glob)
      - identities:
          - type: OCIRegistry
            hostname: ghcr.io
            path: my-org/production
        credentials:
          - type: OCICredentials/v1
            username: prod-user
            password: ghp_production_token
      # Hostname only: matches all other paths on ghcr.io
      - identities:
          - type: OCIRegistry
            hostname: ghcr.io
        credentials:
          - type: OCICredentials/v1
            username: my-user
            password: ghp_your_token_here
    # Docker config: fallback for any registry not matched above
    repositories:
      - repository:
          type: DockerConfig/v1
          dockerConfigFile: "~/.docker/config.json"

Resolution order (see Credential Resolution Tutorial for details):

  1. ghcr.io/my-org/production → uses prod-user (exact path match)
  2. ghcr.io/my-org/staging → uses org-user (glob my-org/* match)
  3. ghcr.io/other-org/repo → uses my-user (hostname-only match)
  4. docker.io/library/nginx → uses Docker config (no consumer matched)

Troubleshooting

Use ocm --loglevel debug to enable debug logging. This shows which consumers are checked and how credentials are resolved.

Symptom: 401 Unauthorized for a registry with explicit credentials

Cause: The consumer identity doesn’t match the request. Common issues: mismatched path or hostname.

Fix: Check that hostname and path match the registry URL exactly. Remember that path: my-org does not match my-org/production.

Symptom: 401 Unauthorized for a registry that should use Docker fallback

Cause: Docker config doesn’t have credentials for that registry.

Fix: Run docker login <registry-hostname>, then retry the OCM command.