Skip to content

Instantly share code, notes, and snippets.

@thejohnny
Forked from jeffwecan/github_jwt_auth.tf
Created April 7, 2022 18:11
Show Gist options
  • Save thejohnny/c38dbfae7613bd9105cfaabd8c5af211 to your computer and use it in GitHub Desktop.
Save thejohnny/c38dbfae7613bd9105cfaabd8c5af211 to your computer and use it in GitHub Desktop.
Example of using GitHub OIDC ID token claims for per-repo K/V path access via templated Vault policies.
variable "github_jwt_issuer_url" {
description = "Issuer URL for GitHub; used in JWT/OIDC auth method configuration."
type = string
default = "https://token.actions.githubusercontent.com"
}
variable "github_org_name" {
type = string
default = "some-github-org"
}
locals {
# These "id_meta" locals are meant to make associated policy paths a little easier to parse within the scope of this
# Terraform configuration.
# The templating syntax within these locals' values is outlined here for reference:
# https://www.vaultproject.io/docs/concepts/policies#templated-policies
id_meta_prefix = "identity.entity.aliases.${vault_jwt_auth_backend.github_jwt.accessor}.metadata"
id_meta = {
repository = "{{ ${local.id_meta_prefix}.repository }}"
}
}
data "vault_policy_document" "example" {
rule {
path = "auth/token/lookup-self"
capabilities = ["read"]
}
rule {
path = "auth/token/revoke-self"
capabilities = ["update"]
}
rule {
description = "Allow reading values under a key/value path of the form: kv/data/github/<github_org>/<repository_name>"
path = "kv/data/github/${local.id_meta.repository}"
capabilities = ["read", "list"]
}
}
resource "vault_policy" "example" {
name = "per-repo-kv-paths-example"
policy = data.vault_policy_document.example.hcl
}
resource "vault_jwt_auth_backend" "github_jwt" {
path = "github-jwt"
type = "jwt"
oidc_discovery_url = var.github_jwt_issuer_url
bound_issuer = var.github_jwt_issuer_url
default_role = "github-actions-job"
}
resource "vault_jwt_auth_backend_role" "example" {
backend = vault_jwt_auth_backend.github_jwt.path
role_type = "jwt"
role_name = vault_jwt_auth_backend.github_jwt.default_role
token_ttl = 60 * 30 # 30 minutes
token_max_ttl = 4 * 60 * 60 # 4 hours
token_policies = [
vault_policy.example.name
]
# Note: on the GitHub "ACTIONS_ID_TOKEN_REQUEST_URL" side of things:
# > By default, this is the URL of the repository owner, such as the organization that owns the repository
bound_audiences = [
"https://github.com/${var.github_org_name}",
]
bound_claims = {
repository_owner = var.github_org_name
}
user_claim = "sub"
groups_claim = "repository"
# Bonus metadata mapping; values are fields in the GitHub JWT,
# keys are their destination Vault token metadata entries.
claim_mappings = {
repository = "repository"
repository_owner = "repository_owner"
event_name = "event_name"
workflow = "workflow"
actor = "actor"
run_id = "run_id"
environment = "environment"
# Other token claims available for mapping to the corresponding Vault identity alias.
# To avoid inflating entity sizes to no end, these claims are not currently being mapped.
# However, a subset of these claims might find usage in the future:
#
# run_number = "run_number"
# run_attempt = "run_attempt"
#
# ref = "ref"
# base_ref = "base_ref"
# head_ref = "head_ref"
# job_workflow_ref = "job_workflow_ref"
# ref_type = "ref_type"
# sha = "sha"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment