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.jsonand 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
| Control | CLI Option | Meaning |
|---|---|---|
| Repository | --repo=owner/repository | GitHub repository allowed to request access |
| Repository ID | --repository-id=123456789 | This option sets an explicit immutable ID. LPM CLI gets the ID from GitHub by default |
| Workflow | --workflow=.github/workflows/deploy.yml | Exact workflow file allowed to request access |
| Branch | --branch=main | This option sets an allowed branch. It accepts a comma-separated list |
| Environment | --env=production | This option selects the env that the job receives. It accepts a comma-separated list |
| Event | --events=push | This option sets allowed GitHub event names. The default is push |
| Forks | --allow-forks | This 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:
- Verifies the OIDC token's signature, issuer, audience, and current claims.
- Selects the exact server-issued policy ID.
- Matches the provider identity, repository or project ID, workflow, branch, event, environment, and fork status against the policy.
- Issues access scoped to that vault and environment.
- Uses the escrowed wrapping material to decrypt the personal vault.
- Returns only the authorized environment as plaintext over TLS.
| Operation | Can LPM.dev Registry read vault values? |
|---|---|
Ordinary lpm env push or developer-machine pull | No |
lpm env oidc allow escrow upload | Receives protected key material for later server decryption |
Authorized lpm env pull --oidc | Yes |
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.