Initial Setup

AWS Cognito configuration:

resource "aws_cognito_user_pool_client" "vault_prod" {
  name         = "vault_prod"
  user_pool_id = aws_cognito_user_pool.main.id
  callback_urls = [
    "http://localhost:8250/oidc/callback", # need for login via vault cli
    "https://<vault address>/oidc/callback",
    "https://<vault address>/ui/vault/auth/oidc/oidc/callback"
  ]
  explicit_auth_flows = [
    "ALLOW_CUSTOM_AUTH",
    "ALLOW_REFRESH_TOKEN_AUTH",
    "ALLOW_USER_SRP_AUTH"
  ]
  generate_secret                      = true
  allowed_oauth_flows_user_pool_client = true
  allowed_oauth_flows                  = ["code"]
  allowed_oauth_scopes                 = ["email", "openid", "profile"]
  supported_identity_providers         = ["COGNITO"]
}

Hashicorp Vault configuration:

resource "vault_jwt_auth_backend" "staff" {
  path        = "oidc"
  type        = "oidc"
  description = "GreatCognito"

  oidc_discovery_url = "https://cognito-idp.eu-west-1.amazonaws.com/<User pool ID>"
  oidc_client_id     = "<OIDC Client ID>"
  oidc_client_secret = "<OIDC Client secret>"

  default_role = "default"

  tune {
    listing_visibility = "unauth"
    default_lease_ttl  = "1h"
    max_lease_ttl      = "24h"
    token_type         = "default-service"
  }
}

resource "vault_jwt_auth_backend_role" "staff-role-default" {
  backend = vault_jwt_auth_backend.staff.path

  role_name    = "default"
  user_claim   = "email"
  groups_claim = "cognito:groups"

  bound_audiences = [
    "<OIDC Client ID>"
  ]

  token_policies = [
    "default"
  ]

  allowed_redirect_uris = [
    "https://<vault address>/oidc/callback",
    "https://<vault address>/ui/vault/auth/oidc/oidc/callback",
    "http://localhost:8250/oidc/callback"
  ]

  depends_on = [
    vault_jwt_auth_backend.staff
  ]
}

Granting access to users via AWS Cognito groups

Configure AWS Cognito groups:

resource "aws_cognito_user_group" "vault_prod_admin" {
  name         = "vault_prod_admin"
  user_pool_id = aws_cognito_user_pool.main.id
}

Configure Hashicorp Vault policies:

resource "vault_identity_group" "vault_prod_admin" {
  name = "vault_prod_admin"
  type = "external"

  policies = ["default", "vault_admins"]
}

resource "vault_identity_group_alias" "vault_prod_admin" {
  name           = "vault_prod_admin"
  mount_accessor = vault_jwt_auth_backend.staff.accessor
  canonical_id   = vault_identity_group.vault_prod_admin.id
}

Remarks

Login via vault cli:

vault login -method=oidc