I am trying to set up the following in Hashicorp Vault:
GitHub Actions authenticates to Vault using JWT auth method. Vault creates an Identity Token containing the repo name. Actions can then use this token to authenticate to a Snowflake database, where I've set up Vault as an External OAuth server. The repo name will be used as the username in snowflake.
Here's the role with my token template:
resource "vault_identity_oidc_role" "github_actions" {
namespace = vault_namespace.namespace.path
name = "github_actions"
client_id = "https://mine.eu-north-1.aws.snowflakecomputing.com"
key = vault_identity_oidc_key.key.name
template = <<EOF
{
"scp": "session:role:${var.snowflake_role}",
"username": {{identity.entity.aliases.${vault_jwt_auth_backend.github_actions.accessor}.name}}
}
EOF
}
Everything seems like it should work fine. I get a token, it's valid, and Snowflake accepts it. But it tells me the username is "wrong". Testing manually, I found that usernames containing special characters just aren't accepted by snowflake. And using the repository field from GitHub gives me a username like "repo-owner/repo-name" which contains slashes and dashes and whatnot.
I'm thinking that if I can just manipulate this value in the token (replace slashes with "SLASH" or something), I'll end up with a username that Snowflake will accept. Is this possible, and if so, how?
You can tackle this on the JWT auth method.
The GitHub OIDC documentation shows a sample token that includes the field repository_id
, which is simply a number with no problematic characters, so my first thought would be to switch to leveraging that field when creating your aliases.
If that repository_id
field is NOT globally unique, I would create a different JWT Auth Method per GitHub organization that you're supporting. That way, you don't need to have the organization referenced in the alias name to create a unique alias, and the GitHub organization is defined by the location of the auth method mount. (vault auth enable -path="github.com/org-name" jwt
might be a reasonable path in this pattern.)
If that repository_id
field IS globally unique, then you only need to switch to that field in the JWT role definition user_claim
parameter and you're done.
Yes, this will make things less user-friendly and more arcane - in order to resolve the repository ID, you'll have to do a GitHub API call, which will make audit log review include additional steps - but I don't see any other point at which you have control over the strings in the auth flow.