OIDC for CI

OIDC lets an authorized GitHub Actions or GitLab.com CI job pull one environment from a personal Pro env project. CI stores no long-lived Registry token.

This flow is an explicit exception to ordinary end-to-end encrypted cloud sync. LPM.dev Registry decrypts the selected environment on the server after verifying the workflow identity and policy.

The currently functional workflow is:

  • A personal Pro vault.
  • GitHub Actions or GitLab.com CI.
  • A repository checkout that contains the project's lpm.json and vault ID.

Organization-vault escrow is not currently supported end-to-end.

Push the Personal Vault First

Create the local vault, sign in, and upload its encrypted cloud copy:

lpm env set --env=production API_TOKEN=secret
lpm login
lpm env push

OIDC escrow cannot be enabled before that personal cloud vault exists.

Authorize a Workflow

Run this on the LPM CLI installation that holds the personal wrapping key:

lpm env oidc allow \
  --provider=github \
  --repo=owner/repository \
  --workflow=.github/workflows/deploy.yml \
  --branch=main \
  --env=production \
  --events=push

The command creates the policy and then uploads protected escrow material that lets LPM.dev Registry decrypt this vault for an authorized CI pull.

After the command succeeds, it prints a server-issued policy ID. Copy this UUID into the CI configuration as LPM_OIDC_POLICY_ID.

The policy ID is a selector, not a bearer credential. It cannot authorize a pull without a valid CI identity token. Protect its integrity because a changed value can select the wrong policy.

By default, LPM CLI gets the immutable numeric repository ID from the GitHub API. Public repository requests do not need GitHub authentication.

If the repository is private, set GITHUB_TOKEN or GH_TOKEN. You can also pass --repository-id=<numeric-id> directly.

The policy binds the repository name and numeric ID. Both values must match during the OIDC exchange and the CI pull.

If a repository is renamed or transferred, run lpm env oidc allow again with its current name. A different repository cannot reuse the old policy.

Existing GitHub policies without a repository ID fail closed. If lpm env oidc list reports a missing ID, run lpm env oidc allow again.

Continue only when LPM CLI reports that CI escrow is enabled. If the escrow upload fails, the command exits with an error.

The policy can already exist after this error, but the CI pull is not ready. Correct the error and run the same command again.

List the vault's current policies with:

lpm env oidc list

The current LPM CLI can create and list policies, but it does not yet provide an oidc revoke command.

Policy Controls

ControlCLI OptionMeaning
Repository--repo=owner/repositoryGitHub repository allowed to request access
Repository ID--repository-id=123456789This option sets an explicit immutable ID. LPM CLI gets the ID from GitHub by default
Workflow--workflow=.github/workflows/deploy.ymlExact workflow file allowed to request access
Branch--branch=mainThis option sets an allowed branch. It accepts a comma-separated list
Environment--env=productionThis option selects the env that the job receives. It accepts a comma-separated list
Event--events=pushThis option sets allowed GitHub event names. The default is push
Forks--allow-forksThis option permits eligible fork-originated runs. Fork access is disabled by default

The workflow file is mandatory. Keep production access restricted to the smallest repository, workflow, branch, event, and environment set that needs it.

GitHub Actions

The job needs id-token: write so GitHub can issue its signed identity token:

name: Deploy

on:
  push:
    branches: [main]

permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 22

      - name: Install LPM CLI
        run: npm install -g @lpm-registry/cli

      - name: Pull production environment
        run: lpm env pull --oidc --env=production --output=.env
        env:
          LPM_OIDC_POLICY_ID: ${{ vars.LPM_OIDC_POLICY_ID }}

      - name: Run the deployment
        run: node --env-file=.env ./scripts/deploy.mjs

--output accepts a file path and writes a plaintext dotenv file. Without --output, LPM CLI reports how many values were returned but does not inject them into later workflow steps. --output=- creates a file named -; it is not stdout.

Use a deployment command that explicitly loads the generated file. The file is set to owner-only permissions where the runner supports POSIX file modes.

The checked-out lpm.json must contain the vault ID used when the policy was created.

Create LPM_OIDC_POLICY_ID as a GitHub repository variable for this job. If you use an environment variable, add environment: <name> to the job. GitHub does not expose an environment variable to a job that does not target that environment.

You can pass --policy-id=<uuid> instead. The command flag takes precedence over LPM_OIDC_POLICY_ID.

GitLab.com CI

Authorize the numeric GitLab project ID from a logged-in development machine:

lpm env oidc allow \
  --provider=gitlab \
  --project-id=12345 \
  --branch=main \
  --env=production

Create LPM_OIDC_POLICY_ID as a GitLab CI/CD variable. Mark it protected only when every branch or tag allowed by the OIDC policy is also protected. GitLab does not expose protected variables to unprotected refs.

deploy:
  id_tokens:
    LPM_OIDC_TOKEN:
      aud: https://lpm.dev
  script:
    - npm install -g @lpm-registry/cli
    - lpm env pull --oidc --env=production --output=.env
    - node --env-file=.env ./scripts/deploy.mjs

Trust Boundary

The CI job obtains an OIDC identity token at run time. LPM CLI sends that token, the policy ID, the vault ID, and the requested environment.

LPM.dev Registry then:

  1. Verifies the OIDC token's signature, issuer, audience, and current claims.
  2. Selects the exact server-issued policy ID.
  3. Matches the provider identity, repository or project ID, workflow, branch, event, environment, and fork status against the policy.
  4. Issues access scoped to that vault and environment.
  5. Uses the escrowed wrapping material to decrypt the personal vault.
  6. Returns only the authorized environment as plaintext over TLS.
OperationCan LPM.dev Registry read vault values?
Ordinary lpm env push or developer-machine pullNo
lpm env oidc allow escrow uploadReceives protected key material for later server decryption
Authorized lpm env pull --oidcYes

If server-side decryption is outside the project's security requirements, do not enable OIDC escrow.

Escrow Errors

If a CI pull reports a stale escrow key, run lpm env oidc allow again on the machine that holds the current wrapping key.

If a CI pull reports an unavailable escrow key version, the Registry configuration needs operator action. The pull fails and returns no secret values.

The Registry protects escrow material with a versioned server key. A server-key rotation does not change the policy or require a new escrow upload.

Current Limitations

  • OIDC env pull requires a personal Pro vault.
  • Organization vaults cannot upload CI escrow or complete an OIDC env pull.
  • GitLab.com policies use the stable numeric project ID. Self-managed GitLab issuers are not supported.
  • The dashboard does not provide personal env OIDC policy management.

For detailed CLI behavior, see the LPM CLI environment reference.

See Also

  • Cloud Sync — Understand the personal encrypted vault and escrow exception.
  • Organization Sharing — Review the separate organization key model.
  • CI/CD — Configure package installation and publishing in CI.