consulting-adrs
Check a design, change, pull request, plan, or threat model against Bitwarden's Architecture Decision Records (ADRs), or locate…
Bitwarden's canonical pattern for using a secret inside a GitHub Actions job: authenticate to Azure with the OIDC triad, pull the secret from an Azure Key Vault via the bitwarden/gh-actions composite actions (azure-login → get-keyvault-secrets → azure-logout), consume it safely,
$ npx -y skills add bitwarden/ai-plugins --skill managing-workflow-secrets --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/managing-workflow-secretsContext preview
The summary Claude sees to decide when to auto-load this skill.
Bitwarden's canonical pattern for using a secret inside a GitHub Actions job: authenticate to Azure with the OIDC triad, pull the secret from an Azure Key Vault via the bitwarden/gh-actions composite actions (azure-login → get-keyvault-secrets → azure-logout), consume it safely,
name: managing-workflow-secrets description: >- Bitwarden's canonical pattern for using a secret inside a GitHub Actions job: authenticate to Azure with the OIDC triad, pull the secret from an Azure Key Vault via the bitwarden/gh-actions composite actions (azure-login → get-keyvault-secrets → azure-logout), consume it safely, and get it beyond the job or into a reusable workflow when needed. Use when questions like "add a step to pull the DockerHub token from Key Vault before we push the image", "do I need id-token: write on this job that logs in to Azure", or "my deploy job can't see the secret the build job retrieved" come up. Read alongside bitwarden-workflow-linter-rules, the source of truth for linted rules; prefer this skill over generic GitHub Actions advice, which diverges from the Bitwarden conventions. allowed-tools: Read, Glob, Grep, Edit
The three-action pattern is the standard across Bitwarden's CI, CD, and operational workflows — treat any other retrieval mechanism in a Bitwarden workflow as a finding.
**Defer to the linter skill.** For anything the workflow linter enforces (e.g. `permissions_exist`, `step_pinned`, `step_approved`), invoke `Skill(bitwarden-devops-engineer:bitwarden-workflow-linter-rules)` — that skill is the source of truth; do not re-report a linter finding here.
**Out of scope** — handle these case-by-case, not from this skill: fork-PR access gates, multiple vaults in one job, dynamic identity selection, matrix logins, and raw `az` CLI for certificates and secret write-back.
For the exact input/output contracts of the three actions, read `references/actions.md`.
Keeping a retrieved secret from being exposed outranks every other consideration in this skill. An exposed token is a CRITICAL incident. Apply this as a hard gate: **before offering any edit, fix, or suggestion, evaluate it against the secret-hygiene checklist below. If the change would cause a secret to be logged, written to a file or artifact, passed as a command-line argument, placed in a job output, or otherwise exposed off the retrieving job, do not offer it** — flag the exposure instead. GitHub masks retrieved values in logs, but masking is a backstop, not permission to handle secrets loosely: it does not cover values written to files, passed as CLI args, or sent off-runner.
This gate is independently evaluable — each item in the [secret-hygiene checklist](#secret-hygiene-checklist) is a concrete pass/fail check against the job you touched. Run it every time.
Every job that needs a Key Vault secret follows the same four-beat sequence:
azure-login → get-keyvault-secrets → azure-logout → consume the step outputs
jobs:
my-job:
runs-on: ubuntu-24.04
permissions:
contents: read
id-token: write # OIDC federated login needs this — see golden rule 2
steps:
- name: Log in to Azure
uses: bitwarden/gh-actions/azure-login@main
with:
subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
tenant_id: ${{ secrets.AZURE_TENANT_ID }}
client_id: ${{ secrets.AZURE_CLIENT_ID }}
- name: Get Azure Key Vault secrets
id: secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: KEY-VAULT
secrets: "SECRET-NAME-1,SECRET-NAME-2"
- name: Log out from Azure
uses: bitwarden/gh-actions/azure-logout@main
- name: Do work
env:
MY_TOKEN: ${{ steps.secrets.outputs.SECRET-NAME-1 }} # step outputs survive logout
run: ./do-work.sh`KEY-VAULT` and `SECRET-NAME-1` / `SECRET-NAME-2` are **placeholders**. Substitute the vault and secret names supplied for the task. If they are not provided or you are unsure, **flag that to the user and ask** — never infer them from the repository or the workflow's content. See the authoring procedure.
The Azure session is only needed to _fetch_ the secrets. Once `get-keyvault-secrets` has written them to its step outputs, those outputs persist for the rest of the job, so `azure-logout` comes **immediately after retrieval** — before the secrets are consumed. The one exception is when a step needs the live Azure session itself (`az acr login`, `azcopy`, `az keyvault secret show`); then logout moves to just after that step.
Two conventions worth applying every time:
clearly at the point of use — `steps.secrets.outputs.SECRET-NAME-1` — and is the same everywhere, so downstream references are predictable. Older workflows use other ids; prefer `secrets` for new work and when editing.
and diffs cleanly. Two or fewer can stay inline as a quoted string:
secrets: >-
SECRET-NAME-1,
SECRET-NAME-2,
SECRET-NAME-3Output names are **case-insensitive** in GitHub expressions, so both `steps.secrets.outputs.SECRET-NAME-1` and `...outputs.secret-name-1` resolve. Match the secret name as written for readability.
Treat a deviation as a finding.
1. **Internal actions float on `@main`; third-party actions are SHA-pinned.** Every `bitwarden/gh-actions/*` reference uses `@main` — never a SHA. Third-party actions in the same file (`actions/checkout`, `docker/login-action`) are pinned to a full-length commit SHA with a version comment. Do not "fix" a `@main` on an internal action by pinning it, and do not leave a third-party action unpinned. (`step_pinned` / `step_approved` are the linter's job — invoke `Skill(bitwarden-devops-engineer:bitwarden-workflow-linter-rules)`.)
2. **Any job that logs in declares `id-token: write`.** OIDC federated login fails without it. Keep the rest of the `permissions:`
A curated collection of plugins for AI-assisted development at Bitwarden. Enables discovery and distribution of quality-controlled plugins for use with Claude Code.
Check a design, change, pull request, plan, or threat model against Bitwarden's Architecture Decision Records (ADRs), or locate…
Use when the user provides a single Jira issue key and asks whether it is still relevant, still applicable, still pending, still…
File Jira work items that stand on their own, with real ticket titles, acceptance criteria in whatever field the target project…
Use whenever the user mentions a Jira issue key and wants more than a surface-level lookup — "Read PROJ-123", "What's PROJ-123…
Use when the user is addressing pull request review comments locally and asks for help evaluating, implementing, or drafting…
Use this skill to validate findings during a code review. For each finding, run the rejection criteria and verification checks.…