Skip to main content
← Back to list
01Issue
FeatureClosedExtensions
Assigneesstack72

#194 Vault backend backed by GitHub Actions Secrets (read via gh token)

Opened by bixu · 5/1/2026

Problem

For many projects, secrets fall into two natural buckets:

  1. Multi-purpose, multi-system secrets — credentials that are used by humans and by many tools across many repos. 1Password (or a similar org-wide secret manager) is the right home for these.
  2. Single-repo, automation-only secrets — credentials whose only job is to let this repository's automation work. They're already needed in GitHub Actions, so they live as GitHub Actions Secrets on that repo.

Today, swamp only ships a local_encryption vault backend, which is a third store on top of those two. For repo-scoped secrets in particular, that's the wrong fit: the secret already lives in GitHub Secrets (because CI needs it), and now I have to also mirror it into a swamp vault so that vault.get(...) resolves locally and from the runner. The natural home for these per-repo automation secrets is GitHub Secrets; swamp should be able to read from there directly.

Proposed solution

A new vault backend — e.g. github_actions_secrets — that resolves vault.get(<vault_name>, <KEY>) by reading the <KEY> Actions Secret on the configured GitHub repository (and any org-level secrets it inherits), authenticating via the user's gh CLI token or an explicit GitHub PAT.

Typical setup for a repo whose automation secrets already live in GitHub:

gh auth login                                    # most devs already have this
swamp vault create github_actions_secrets swamp  # one-time, scoped to the current repo
swamp workflow run ci                            # vault.get(swamp, FOO) just works

This lets each project pick the right backend per secret class:

  • Multi-purpose org secrets → keep using 1Password (or whatever the org standard is).
  • Single-repo automation secrets → keep them in GitHub Secrets, where CI already needs them, and let swamp read them via this backend.

No vault put step, no separate encryption key, no per-secret bootstrap, no third source of truth.

Alternatives considered

  1. Mirror GitHub Secrets into a local_encryption vault. Doubles the secret list and drifts as GitHub Secrets are added/rotated.
  2. Mirror GitHub Secrets into 1Password. Wrong place — these are repo-scoped automation secrets, and 1Password's value is precisely that it spans repos and humans. Putting per-repo automation secrets there pollutes the namespace.
  3. Read env vars directly from inside extension code. Bypasses the vault abstraction and loses vault.get(...) ergonomics in workflow YAML.

Impact

Concrete example from hivemq/swamp-extensions: reproducing the harvester/kubeconfig bug in issue #53 required mirroring HARVESTER_ADMIN_PASSWORD_{PROD,DEV} into a local local_encryption vault, even though those values are already first-class GitHub Secrets on the same repo (and need to be there for CI). A github_actions_secrets backend would let that bootstrap step disappear and would let us route per-repo automation secrets to their natural home.

02Bog Flow
OPENTRIAGEDIN PROGRESSCLOSED+ 1 MOREASSIGNEDCLASSIFICATION

Closed

5/8/2026, 12:37:07 PM

No activity in this phase yet.

03Sludge Pulse
stack72 assigned stack725/7/2026, 6:11:56 PM
Editable. Press Enter to edit.

stack72 commented 5/8/2026, 12:37:06 PM

Unfortunately, the GitHub REST API does not expose secret values. GET /repos/{owner}/{repo}/actions/secrets/{secret_name} returns only metadata (name, created/updated timestamps) — never the secret string itself. This is a deliberate GitHub security decision: secret values are sealed with the repo's public key at write time and only decrypted inside GitHub Actions runners at workflow execution time.

This means vault.get(swamp, FOO) cannot retrieve a secret's value via a gh CLI token or PAT — not locally, and not even from a self-hosted runner outside of the Actions execution context. The core operation the vault backend needs doesn't have an API to call.

bixu commented 5/9/2026, 8:31:48 AM

Go it, thanks anyway.

Sign in to post a ripple.