secret-santa

module
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 20, 2026 License: Apache-2.0

README

Secret Santa

Secret Santa

Kubernetes operator for generating secrets with templates and storing them in multiple destinations.

It plays well with Kubernetes External Secrets too.

Visit Project Page

Features

  • Multiple Storage: Kubernetes secrets, AWS Secrets Manager, AWS Parameter Store, Azure Key Vault, GCP Secret Manager, HashiCorp Vault
  • Template Engine: Go templates with crypto, random, and TLS generators
  • Create-Once: Secrets generated once and never modified
  • Cloud Integration: AWS, Azure, GCP, and HashiCorp Vault authentication support
  • Dry-Run Mode: Validate templates and preview masked output without creating secrets
  • Metadata: Automatic metadata for traceability and observability

Installation

helm repo add logiciq https://charts.logiciq.ca
helm install secret-santa logiciq/secret-santa
AWS Setup (Optional)

For AWS Secrets Manager or Parameter Store:

# With service account annotations (EKS)
helm install secret-santa logiciq/secret-santa \
  --set aws.enabled=true \
  --set aws.region=us-west-2 \
  --set serviceAccount.annotations."eks\.amazonaws\.com/role-arn"=arn:aws:iam::123456789012:role/secret-santa

# With environment variables
helm install secret-santa logiciq/secret-santa \
  --set aws.enabled=true \
  --set aws.region=us-west-2 \
  --set aws.credentials.useServiceAccount=false \
  --set aws.credentials.accessKeyId=AKIA... \
  --set aws.credentials.secretAccessKey=...
Azure Setup (Optional)

For Azure Key Vault:

# With service principal
# amazonq-ignore-next-line
helm install secret-santa logiciq/secret-santa \
  --set azure.enabled=true \
  --set azure.tenantId=00000000-0000-0000-0000-000000000000 \
  --set azure.credentials.useManagedIdentity=false \
  --set azure.credentials.clientId=00000000-0000-0000-0000-000000000000 \
  --set azure.credentials.clientSecret=your-client-secret

# With managed identity (AKS)
helm install secret-santa logiciq/secret-santa \
  --set azure.enabled=true \
  --set azure.tenantId=00000000-0000-0000-0000-000000000000 \
  --set azure.credentials.useManagedIdentity=true \
  --set serviceAccount.annotations."azure\.workload\.identity/client-id"=00000000-0000-0000-0000-000000000000
HashiCorp Vault Setup (Optional)

For HashiCorp Vault:

# With Kubernetes auth (recommended in-cluster)
helm install secret-santa logiciq/secret-santa \
  --set vault.enabled=true \
  --set vault.address=https://vault.example.com \
  --set vault.authMethod=kubernetes \
  --set vault.role=secret-santa

# With token auth
helm install secret-santa logiciq/secret-santa \
  --set vault.enabled=true \
  --set vault.address=https://vault.example.com \
  --set vault.token=<vault-token>
GCP Setup (Optional)

For GCP Secret Manager:

# With service account key file
# amazonq-ignore-next-line
helm install secret-santa logiciq/secret-santa \
  --set gcp.enabled=true \
  --set gcp.projectId=my-project-id \
  --set gcp.credentials.useWorkloadIdentity=false \
  --set gcp.credentials.keyFile=/etc/gcp/key.json \
  --set gcp.credentials.existingSecret=gcp-service-account-key

# With workload identity (GKE)
helm install secret-santa logiciq/secret-santa \
  --set gcp.enabled=true \
  --set gcp.projectId=my-project-id \
  --set gcp.credentials.useWorkloadIdentity=true \
  --set serviceAccount.annotations."iam\.gke\.io/gcp-service-account"=secret-santa@my-project.iam.gserviceaccount.com

Quick Start

Dry-Run Mode

Validate templates and preview output without creating secrets:

apiVersion: secrets.secret-santa.io/v1alpha1
kind: SecretSanta
metadata:
  name: dry-run-example
spec:
  dryRun: true
  template: |
    {
      "password": "{{ .pass.value }}",
      "api_key": "{{ .key.value }}"
    }
  generators:
    - name: pass
      type: random_password
      config:
        length: 32
    - name: key
      type: random_string
      config:
        length: 64

Check the status for masked output:

kubectl get secretsanta dry-run-example -o yaml
# status.dryRunResult.maskedOutput shows structure with <MASKED> values
Basic Password Generation (Kubernetes Secret)
apiVersion: secrets.secret-santa.io/v1alpha1
kind: SecretSanta
metadata:
  name: app-password
spec:
  template: |
    password: {{ .pass.password }}
  generators:
    - name: pass
      type: random_password
      config:
        length: 32
  media:
    type: k8s  # Default - can be omitted
TLS Certificate (Kubernetes Secret)
apiVersion: secrets.secret-santa.io/v1alpha1
kind: SecretSanta
metadata:
  name: tls-cert
spec:
  template: |
    tls.crt: {{ .cert.certificate }}
    tls.key: {{ .key.private_key_pem }}
  generators:
    - name: key
      type: tls_private_key
    - name: cert
      type: tls_self_signed_cert
      config:
        key_pem: "{{ .key.private_key_pem }}"
        subject:
          common_name: example.com
  secretType: kubernetes.io/tls
  media:
    type: k8s  # Default - can be omitted
AWS Secrets Manager
apiVersion: secrets.secret-santa.io/v1alpha1
kind: SecretSanta
metadata:
  name: aws-secret
spec:
  template: |
    {
      "username": "admin",
      "password": "{{ .pass.password }}"
    }
  generators:
    - name: pass
      type: random_password
      config:
        length: 24
  media:
    type: aws-secrets-manager
    config:
      region: us-west-2
      kms_key_id: alias/secrets-key
AWS Parameter Store
apiVersion: secrets.secret-santa.io/v1alpha1
kind: SecretSanta
metadata:
  name: db-url
spec:
  template: |
    postgresql://user:{{ .pass.password }}@db.example.com/app
  generators:
    - name: pass
      type: random_password
      config:
        length: 32
  media:
    type: aws-parameter-store
    config:
      region: us-east-1
      parameter_name: /app/database-url
Azure Key Vault
apiVersion: secrets.secret-santa.io/v1alpha1
kind: SecretSanta
metadata:
  name: azure-secret
spec:
  template: |
    {
      "username": "admin",
      "password": "{{ .pass.password }}"
    }
  generators:
    - name: pass
      type: random_password
      config:
        length: 24
  media:
    type: azure-key-vault
    config:
      vault_url: https://my-vault.vault.azure.net
      secret_name: app-credentials
GCP Secret Manager
apiVersion: secrets.secret-santa.io/v1alpha1
kind: SecretSanta
metadata:
  name: gcp-secret
spec:
  template: |
    {
      "username": "admin",
      "password": "{{ .pass.password }}"
    }
  generators:
    - name: pass
      type: random_password
      config:
        length: 24
  media:
    type: gcp-secret-manager
    config:
      project_id: my-gcp-project
      secret_name: app-credentials
HashiCorp Vault
apiVersion: secrets.secret-santa.io/v1alpha1
kind: SecretSanta
metadata:
  name: vault-secret
spec:
  template: |
    {
      "username": "admin",
      "password": "{{ .pass.password }}"
    }
  generators:
    - name: pass
      type: random_password
      config:
        length: 24
  media:
    type: hashicorp-vault
    config:
      address: https://vault.example.com
      mount_path: secret
      path: myapp/credentials
      auth_method: kubernetes
      role: secret-santa

Storage Destinations

Kubernetes Secrets (Default)
# Default media - can be omitted entirely
media:
  type: k8s

# Or with custom secret name
media:
  type: k8s
  config:
    secret_name: my-custom-secret-name
AWS Secrets Manager
media:
  type: aws-secrets-manager
  config:
    region: us-west-2                    # Optional
    secret_name: my-custom-secret        # Optional
    kms_key_id: alias/my-kms-key        # Optional
AWS Parameter Store
media:
  type: aws-parameter-store
  config:
    region: us-east-1                    # Optional
    parameter_name: /my/custom/param     # Optional
    kms_key_id: alias/my-kms-key        # Optional
Azure Key Vault
media:
  type: azure-key-vault
  config:
    vault_url: https://my-vault.vault.azure.net  # Required
    secret_name: my-custom-secret                # Optional
    tenant_id: 00000000-0000-0000-0000-000000000000  # Optional - uses default if empty
GCP Secret Manager
media:
  type: gcp-secret-manager
  config:
    project_id: my-gcp-project           # Required
    secret_name: my-custom-secret        # Optional
    credentials_file: /path/to/key.json  # Optional - uses workload identity if empty
HashiCorp Vault
media:
  type: hashicorp-vault
  config:
    address: https://vault.example.com   # Optional - uses VAULT_ADDR env if empty
    mount_path: secret                   # Optional - defaults to "secret"
    path: myapp/credentials              # Optional - defaults to namespace/name
    auth_method: kubernetes              # Optional - "kubernetes" or omit for token
    role: secret-santa                   # Optional - Vault role for kubernetes auth
    token: <vault-token>                 # Optional - use for token auth

Generators

Random
  • random_password - Secure passwords
  • random_string - Random strings
  • random_uuid - UUIDs
  • random_bytes - Byte arrays
TLS
  • tls_private_key - Private keys
  • tls_self_signed_cert - Self-signed certificates
  • tls_cert_request - Certificate requests
Crypto
  • crypto_aes_key - AES keys
  • crypto_rsa_key - RSA keys
  • crypto_ed25519_key - Ed25519 keys

Configuration

Helm Values
controller:
  replicas: 1
  args:
    maxConcurrentReconciles: 5
    watchNamespaces: ["default", "production"]
    logLevel: "info"

aws:
  enabled: true
  region: us-west-2
  credentials:
    useServiceAccount: true

azure:
  enabled: true
  tenantId: 00000000-0000-0000-0000-000000000000
  credentials:
    useManagedIdentity: true
    # OR for service principal:
    # useManagedIdentity: false
    # clientId: 00000000-0000-0000-0000-000000000000
    # existingSecret: azure-credentials
    # existingSecretKey: client-secret

gcp:
  enabled: true
  projectId: my-gcp-project
  credentials:
    useWorkloadIdentity: true
    # OR for service account key:
    # useWorkloadIdentity: false
    # existingSecret: gcp-service-account-key
    # existingSecretKey: key.json

vault:
  enabled: true
  address: https://vault.example.com
  authMethod: kubernetes
  role: secret-santa
  # OR for token auth:
  # authMethod: ""
  # token: <vault-token>

serviceAccount:
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/secret-santa
    azure.workload.identity/client-id: 00000000-0000-0000-0000-000000000000
    iam.gke.io/gcp-service-account: secret-santa@my-project.iam.gserviceaccount.com
Environment Variables
SECRET_SANTA_MAX_CONCURRENT_RECONCILES=5
SECRET_SANTA_WATCH_NAMESPACES=default,production
SECRET_SANTA_LOG_LEVEL=debug
SECRET_SANTA_DRY_RUN=true
SECRET_SANTA_ENABLE_METADATA=false
AWS_REGION=us-west-2
AZURE_TENANT_ID=00000000-0000-0000-0000-000000000000
AZURE_CLIENT_ID=00000000-0000-0000-0000-000000000000
GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json
GCP_PROJECT_ID=my-gcp-project
VAULT_ADDR=https://vault.example.com
VAULT_TOKEN=<vault-token>

Dry-Run and Validation

Template Validation

Use dryRun: true to validate templates and generator configurations:

  • Validates template syntax
  • Checks generator types and configurations
  • Executes generators and templates
  • Masks sensitive output in status
  • No secrets are created
Status Output
status:
  dryRunResult:
    maskedOutput: |
      {
        "password": "<MASKED>",
        "api_key": "<MASKED>"
      }
    generatorsUsed:
      - "pass (random_password)"
      - "key (random_string)"
    executionTime: "2024-01-15T10:30:00Z"
  conditions:
    - type: DryRunComplete
      status: "True"
      message: "Dry-run completed successfully with masked output"
Global Dry-Run

Enable dry-run for all resources via controller flag:

helm install secret-santa logiciq/secret-santa \
  --set controller.args.dryRun=true

Secret Metadata

Automatic metadata is added to all generated secrets for traceability:

Kubernetes Secrets (Annotations)
  • secrets.secret-santa.io/created-at: Creation timestamp
  • secrets.secret-santa.io/generator-types: Generator types used
  • secrets.secret-santa.io/template-checksum: Template checksum
  • secrets.secret-santa.io/source-cr: Source SecretSanta reference
AWS/Azure/GCP/Vault (Tags/Labels/Metadata)

Same metadata keys with platform-specific formatting.

Disable Metadata
helm install secret-santa logiciq/secret-santa \
  --set controller.args.enableMetadata=false

Directories

Path Synopsis
api
v1alpha1
Package v1alpha1 contains API Schema definitions for the secrets v1alpha1 API group +kubebuilder:object:generate=true +groupName=secrets.secret-santa.io
Package v1alpha1 contains API Schema definitions for the secrets v1alpha1 API group +kubebuilder:object:generate=true +groupName=secrets.secret-santa.io
internal
pkg

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL