{"id":50510835,"url":"https://github.com/keycardai/gha-keycard-auth","last_synced_at":"2026-06-02T20:02:42.779Z","repository":{"id":358929546,"uuid":"1240098090","full_name":"keycardai/gha-keycard-auth","owner":"keycardai","description":"GitHub Actions action that exchanges a workflow's OIDC token for scoped credentials via Keycard STS. No static secrets in repo settings.","archived":false,"fork":false,"pushed_at":"2026-05-19T17:38:50.000Z","size":278,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-19T19:53:52.013Z","etag":null,"topics":["actions","credentials","github-actions","keycard","oauth2","oidc","sts"],"latest_commit_sha":null,"homepage":"https://docs.keycard.ai","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/keycardai.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-15T19:07:53.000Z","updated_at":"2026-05-19T17:38:53.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/keycardai/gha-keycard-auth","commit_stats":null,"previous_names":["keycardai/gha-keycard-auth"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/keycardai/gha-keycard-auth","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keycardai%2Fgha-keycard-auth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keycardai%2Fgha-keycard-auth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keycardai%2Fgha-keycard-auth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keycardai%2Fgha-keycard-auth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/keycardai","download_url":"https://codeload.github.com/keycardai/gha-keycard-auth/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keycardai%2Fgha-keycard-auth/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33834011,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-02T02:00:07.132Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["actions","credentials","github-actions","keycard","oauth2","oidc","sts"],"created_at":"2026-06-02T20:02:41.875Z","updated_at":"2026-06-02T20:02:42.774Z","avatar_url":"https://github.com/keycardai.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# gha-keycard-auth\n\n[![Release](https://img.shields.io/github/v/release/keycardai/gha-keycard-auth?label=release)](https://github.com/keycardai/gha-keycard-auth/releases/latest)\n[![CI](https://github.com/keycardai/gha-keycard-auth/actions/workflows/ci.yml/badge.svg)](https://github.com/keycardai/gha-keycard-auth/actions/workflows/ci.yml)\n[![CodeQL](https://github.com/keycardai/gha-keycard-auth/actions/workflows/codeql.yml/badge.svg)](https://github.com/keycardai/gha-keycard-auth/actions/workflows/codeql.yml)\n[![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](./LICENSE)\n\nGitHub Actions action that exchanges a workflow's OIDC token for credentials via Keycard STS.\n\n[Keycard](https://keycard.ai) is an identity broker for non-human workloads — it issues short-lived, scoped credentials to a workflow (or service, or agent) based on the identity it can prove it has.\n\n## Why\n\nWorkflows present their OIDC identity to Keycard and get back scoped credentials. No static secrets in repo settings, no `secrets: inherit` blast radius, audit per credential per run.\n\n## Quickstart\n\n\u003e **Prerequisite:** a Keycard zone configured to trust GitHub's OIDC provider. See [Setup](#setup).\n\n```yaml\npermissions:\n  id-token: write\n  contents: read\n\nsteps:\n  - uses: keycardai/gha-keycard-auth@\u003csha\u003e\n    with:\n      zone-url: https://\u003cid\u003e.keycard.cloud\n      credentials: |\n        - resource: urn:fly:app:my-app:deploy-token\n          type: env\n          env-name: FLY_API_TOKEN\n          scope: deploy:write\n  - run: flyctl deploy\n```\n\nFor credentials that need to be on disk (e.g. a PEM private key), use `type: file`:\n\n```yaml\ncredentials: |\n  - resource: urn:secret:gh-app-key\n    type: file\n    file-path: gh-app.pem      # resolved under $RUNNER_TEMP/keycard-auth/\n    file-mode: \"0400\"          # must be quoted — see file-mode notes below\n```\n\n## Providers\n\nBeyond raw env/file distribution, the action can broker credentials to specific downstream identity providers. A **provider** takes the Keycard zone JWT, performs the second-hop exchange with the downstream IdP (e.g. RFC 8693 token exchange to Pulumi), and exports the resulting credential into the workflow's environment. The workflow author writes one step; the Keycard zone controls the JWT's claims; the downstream's allow policy controls what the resulting credential can do.\n\n**Supported providers:**\n\n| Type | Downstream | Default output env var |\n|---|---|---|\n| `pulumi` | Pulumi Cloud (RFC 8693 to `/api/oauth/token`) | `PULUMI_ACCESS_TOKEN` |\n\n### `pulumi`\n\n```yaml\nsteps:\n  - uses: keycardai/gha-keycard-auth@\u003csha\u003e\n    with:\n      zone-url: https://\u003cid\u003e.keycard.cloud\n      credentials: |\n        - resource: urn:pulumi:org:keycardlabs\n          type: pulumi\n          pulumi:\n            organization: keycardlabs\n  - run: pulumi preview --stack acme/prod\n```\n\n| Field | Required | Notes |\n|---|---|---|\n| `pulumi.organization` | yes | Pulumi organization the issued token is scoped to. Becomes `audience=urn:pulumi:org:\u003corg\u003e` in the exchange request. |\n| `pulumi.token-type` | no | `organization` (default), `team`, or `personal`. Maps to `urn:pulumi:token-type:access_token:\u003cvalue\u003e`. |\n| `pulumi.cloud-url` | no | Pulumi API origin, default `https://api.pulumi.com`. Must be https; path is stripped. |\n\nDownstream setup: register the Keycard zone as an OIDC issuer in Pulumi Cloud (Settings → Access Management → OIDC Issuers), and add an allow policy matching `aud=urn:pulumi:org:\u003corg\u003e` plus the `sub`/`client_id` claim shape Keycard mints for your workflows. This replaces `pulumi/auth-actions` in workflows that want credential issuance + audit flowing through Keycard.\n\n### Adding a provider\n\nProviders ship inside this action — there is no runtime plugin mechanism. See [CONTRIBUTING.md](./CONTRIBUTING.md#adding-a-provider) for the step-by-step.\n\n## Inputs\n\n| Input | Required | Description |\n|---|---|---|\n| `zone-url` | yes | Base URL of the Keycard zone. |\n| `audience` | no | Audience for the GHA OIDC token. Defaults to `zone-url`. |\n| `credentials` | yes | YAML list of credential specs (see below). |\n\n### Credential spec\n\n| Field | Required | Notes |\n|---|---|---|\n| `resource` | yes | Keycard resource URN. |\n| `type` | yes | `env`, `file`, or a [provider type](#providers). |\n| `scope` | no | OAuth scope to request on the resource. |\n| `env-name` | when `type=env` | Env var to set. Must match `^[A-Z_][A-Z0-9_]*$` and is not allowed to be a reserved name (e.g. `PATH`, `NODE_OPTIONS`, `LD_PRELOAD`, anything starting with `GITHUB_`/`RUNNER_`/`ACTIONS_`/`INPUT_`). Providers also accept this field as an optional override of their default env var. |\n| `file-path` | when `type=file` | Path on disk. Resolved against an action-managed directory under `$RUNNER_TEMP`; absolute paths and `..` traversal are rejected. |\n| `file-mode` | no | Octal mode for `file`, default `0600`. **Must be a quoted string** (`\"0600\"`) — unquoted YAML coerces it to a decimal integer. Must be owner-only; group/world bits are rejected (so `0640`, `0644`, etc. fail). |\n| `\u003cprovider\u003e` | when `type=\u003cprovider\u003e` | Provider-specific config block. See [Providers](#providers). |\n\n## Setup\n\nYou need a Keycard zone with GitHub Actions configured as a trusted OIDC provider, plus an application and resource to authorize. See the [Keycard documentation](https://docs.keycard.ai) for the step-by-step (console and Terraform).\n\n## Pinning\n\nThis is a `0.x` release line — the API may change between minor versions. Pin to a 40-character commit SHA:\n\n```yaml\nuses: keycardai/gha-keycard-auth@\u003c40-char-sha\u003e   # v0.1.0\n```\n\n[Dependabot](https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot) understands the `# v0.1.0` trailing comment and will open PRs to bump the SHA when a new release lands. To resolve the SHA for a given release manually, use `git rev-parse v0.1.0` or look up the release on GitHub.\n\n## Contributing\n\nExternal contributions welcome via forks and pull requests. See [CONTRIBUTING](./CONTRIBUTING.md). For vulnerabilities see [SECURITY](./SECURITY.md) — please do not file public issues for security reports.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkeycardai%2Fgha-keycard-auth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkeycardai%2Fgha-keycard-auth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkeycardai%2Fgha-keycard-auth/lists"}