Skip to content

Instantly share code, notes, and snippets.

@memes
Last active February 15, 2023 12:00
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save memes/3267553b31ba0f662b8fb601560c53b7 to your computer and use it in GitHub Desktop.
Save memes/3267553b31ba0f662b8fb601560c53b7 to your computer and use it in GitHub Desktop.
Vault OIDC configuration workaround for hashicorp/terraform-provider-vault#957
resource "vault_policy" "admin" {
name = "admin"
policy = <<EOP
# Manage auth methods broadly across Vault
path "auth/*"
{
capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}
# Create, update, and delete auth methods
path "sys/auth/*"
{
capabilities = ["create", "update", "delete", "sudo"]
}
# List auth methods
path "sys/auth"
{
capabilities = ["read"]
}
# List existing policies
path "sys/policies/acl"
{
capabilities = ["list"]
}
# Create and manage ACL policies
path "sys/policies/acl/*"
{
capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}
# Manage secrets engines
path "sys/mounts/*"
{
capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}
# List existing secrets engines.
path "sys/mounts"
{
capabilities = ["read"]
}
# Read health checks
path "sys/health"
{
capabilities = ["read", "sudo"]
}
# List, create, update, and delete KV secrets.
path "secret/*"
{
capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}
# List, create, update, and delete PKI engine.
path "pki/*" {
capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}
# List, create, update, and delete PKI CA engine.
path "pki_ca/*" {
capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}
EOP
}
# Configures GSuite as an OIDC/JWT provider and maps groups to Vault
# aliases to elevate privileges as needed.
resource "vault_jwt_auth_backend" "oidc" {
type = "oidc"
path = "oidc"
oidc_discovery_url = "https://accounts.google.com"
oidc_client_id = var.gsuite_client_id
oidc_client_secret = var.gsuite_client_secret
default_role = "domain_user"
provider_config = {
provider = "gsuite"
gsuite_service_account = var.gsuite_service_account_cred_path
gsuite_admin_impersonate = var.gsuite_admin_impersonate_account
# Manually update this from command line to make sure it is setting all
# params correctly and ignore changes until fixed.
# https://github.com/hashicorp/terraform-provider-vault/issues/957
# fetch_groups = true
# fetch_user_info = false
# groups_recurse_max_depth = 5
user_custom_schemas = ""
}
lifecycle {
ignore_changes = [
provider_config,
]
}
}
resource "vault_jwt_auth_backend_role" "domain_user" {
backend = vault_jwt_auth_backend.oidc.path
role_name = "domain_user"
role_type = vault_jwt_auth_backend.oidc.type
allowed_redirect_uris = [
"https://vault.lab.acceleratedgcp.com:8200/ui/vault/auth/oidc/oidc/callback",
"http://localhost:8250/oidc/callback",
]
user_claim = "sub"
groups_claim = "groups"
# Domain users get default policy always
token_policies = ["default"]
}
# Link the Vault admin policy to the domain admin group
resource "vault_identity_group" "admins" {
name = var.gsuite_admin_group
type = "external"
policies = [
vault_policy.admin.name,
]
metadata = {
responsibility = "Admin Group"
}
}
resource "vault_identity_group_alias" "admins_alias" {
name = var.gsuite_admin_group
mount_accessor = vault_jwt_auth_backend.oidc.accessor
canonical_id = vault_identity_group.admins.id
}
# Write the configuration file that needs to be imported by `vault write -tls-skip-verify auth/oidc/config @oidc.json`
resource "local_file" "oidc_json" {
filename = "oidc.json"
content = jsonencode({
oidc_discovery_url = "https://accounts.google.com"
oidc_client_id = var.gsuite_client_id
oidc_client_secret = var.gsuite_client_secret
default_role = "domain_user"
provider_config = {
provider = "gsuite"
gsuite_service_account = var.gsuite_service_account_cred_path
gsuite_admin_impersonate = var.gsuite_admin_impersonate_account
fetch_groups = true
fetch_user_info = false
groups_recurse_max_depth = 5
user_custom_schemas = ""
}
})
}
# From the OIDC credentials screen: client id and secret
gsuite_client_id = "NNNNNNNNNNNN-xxxxxxxxxxx.apps.googleusercontent.com"
gsuite_client_secret = "XxXxXxXxXxX"
# Path to service account JSON on vault server
gsuite_service_account_cred_path = "/var/lib/vault/vault-sa.json"
# The GSuite *SUPER USER* account that can perform lookups
gsuite_admin_impersonate_account = "admin@example.com"
# The GSuite *GROUP* that will be granted admin policy
gsuite_admin_group = "lab-admins@example.com"
variable "gsuite_client_id" {
type = string
}
variable "gsuite_client_secret" {
type = string
}
variable "gsuite_service_account_cred_path" {
type = string
}
variable "gsuite_admin_impersonate_account" {
type = string
}
variable "gsuite_admin_group" {
type = string
}
@memes
Copy link
Author

memes commented Dec 7, 2022

@teochenglim - this gist outlines a way to work around an historical bug in the Vault provider that was fixed in 2021. If you are using a recent version of the Vault provider you do not need this workaround - e.g. https://github.com/memes/lab-config/blob/main/vault/oidc.tf#L11-L19 shows that the properties can be set correctly from within the provider.

Explanation of gist approach

Bug 957 prevented setting the OIDC properties correctly; if you look at lines 11-22 in oidc.tf you can see that some required properties are commented out because of the bug. Since OIDC against GSuite will fail without those properties, it was necessary to manually apply a JSON file to Vault to fix the missing properties. Essentially configuring OIDC for GSuite through Vault was a two-step process:

  1. Create the resource
  2. Apply JSON to fix missing properties

The example Terraform in this gist creates the Vault OIDC resource with a partial configuration and generates the JSON file that can complete the configuration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment