To secure store secrets used primarily for managed by ArgoCD kubernetes clusters with use Hashicorp Vault.
Vault is installed with ArgoCD in cicd k8s cluster with a helm chart.
https://github.com/SafiBank/SaFiMono/blob/main/devops/argocd/environments/cicd/vault/values.yaml
vault: persistence: enabled: true hostPath: "/vault/file" size: 2Gi ingress: enabled: true hosts: - vault.cicd.safibank.online annotations: cert-manager.io/cluster-issuer: letsencrypt-prod traefik.ingress.kubernetes.io/router.tls: "true" traefik.ingress.kubernetes.io/router.entrypoints: websecure tls: - secretName: vault.cicd.safibank.online-tls hosts: - vault.cicd.safibank.online vault: externalConfig: policies: - name: argocd rules: |- path "secret/data/*" { capabilities = ["read","list"] } auth: - type: kubernetes roles: - name: argocd bound_service_account_names: - argocd-repo-server bound_service_account_namespaces: - argocd policies: - argocd ttl: 1h config: listener: tcp: address: "[::]:8200" tls_disable: true ui: true api_addr: http://localhost:8200 unsealer: image: repository: ghcr.io/banzaicloud/bank-vaults pullPolicy: IfNotPresent args: [ "--mode", "k8s", "--k8s-secret-namespace", "vault", "--k8s-secret-name", "bank-vaults", ]
In values we specify external policy
and auth type
for argocd-vault-replacer. Secrets are stored in persistent volume inside cluster.
Root token can’t be specified and is generated during first start as well as unseal keys and can be viewed in bank-vaults
secret in kubernetes.
Policies for users
and Okta auth type are configured with terraform.
locals { vault_admin_groups = [ "DevOps" ] vault_viewer_groups = [ "Developers" ] vault_label = "vault-cicd" } data "okta_group" "source_okta_vault_admin_group" { for_each = toset(local.vault_admin_groups) name = each.value } data "okta_group" "source_okta_vault_viewer_group" { for_each = toset(local.vault_viewer_groups) name = each.value } resource "okta_group" "vault_admin" { name = "${local.vault_label}-admin" description = "Group of users with admin permissions to the ${local.vault_label}" skip_users = true } resource "okta_group" "vault_viewer" { name = "${local.vault_label}-viewer" description = "Group of users with read permissons to the ${local.vault_label}" skip_users = true } resource "okta_group_rule" "vault_admin_group_rule" { for_each = toset(local.vault_admin_groups) name = "${local.vault_label}_admin_${index(local.vault_admin_groups, each.key)}" expression_value = "isMemberOfGroup(\"${data.okta_group.source_okta_vault_admin_group[each.key].id}\")" group_assignments = [okta_group.vault_admin.id] status = "ACTIVE" } resource "okta_group_rule" "vault_viewer_group_rule" { for_each = toset(local.vault_viewer_groups) name = "${local.vault_label}_viewer_${index(local.vault_viewer_groups, each.key)}" expression_value = "isMemberOfGroup(\"${data.okta_group.source_okta_vault_viewer_group[each.key].id}\")" group_assignments = [okta_group.vault_viewer.id] status = "ACTIVE" } resource "vault_okta_auth_backend" "okta" { description = "Okta" organization = "safibank" token = data.vault_generic_secret.okta.data["api_token"] } resource "vault_okta_auth_backend_group" "vault_admin" { path = vault_okta_auth_backend.okta.path group_name = okta_group.vault_admin.name policies = [vault_policy.vault_admin.name] } resource "vault_okta_auth_backend_group" "vault_viewer" { path = vault_okta_auth_backend.okta.path group_name = okta_group.vault_viewer.name policies = [vault_policy.vault_viewer.name] } resource "vault_policy" "vault_admin" { name = "admin-policy" policy = file("${path.module}/vault-policies/admin.hcl") } resource "vault_policy" "vault_viewer" { name = "viewer-policy" policy = file("${path.module}/vault-policies/viewer.hcl") }
Policies
admin.hcl
# Read system health check path "sys/health" { capabilities = ["read", "sudo"] } # Create and manage ACL policies broadly across Vault # 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"] } # Enable and manage authentication methods broadly across Vault # 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"] } # Enable and manage the key/value secrets engine at `secret/` path # List, create, update, and delete key/value secrets path "secret/*" { 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"] }
viewer.hcl
# Read permission on the k/v secrets path "/secret/*" { capabilities = ["list"] } path "secret/data/dev/apps*" { capabilities = ["read", "list"] } path "secret/data/stage/apps*" { capabilities = ["read", "list"] } path "secret/data/brave/apps*" { capabilities = ["read", "list"] }