Secrets

The secrets resource type manages sensitive data like passwords, API keys, and certificates. Teabar can generate secrets automatically or fetch them from external secret managers.

Basic Usage

spec:
  resources:
    secrets:
      - name: db-password
        type: generated
        spec:
          length: 24

Schema Reference

secrets:
  - name: string              # Required: Secret identifier
    type: string              # Required: Secret type (generated, external, static)
    enabled: boolean          # Optional: Enable/disable this secret (default: true)
    count: integer            # Optional: Create multiple secrets with {{ .Index }}
    spec:                     # Required: Type-specific configuration
      # For 'generated' type
      length: integer         # Password length
      charset: string         # Character set (alphanumeric, alphanumeric-special, numeric, hex)
      
      # For 'external' type
      provider: string        # External provider (vault, aws-secrets-manager, azure-keyvault)
      path: string            # Secret path in provider
      key: string             # Specific key within secret
      
      # For 'static' type
      value: string           # Static secret value (use sparingly!)
    dependsOn:                # Optional: Resource dependencies
      - string

Secret Types

Generated Secrets

Automatically generate secure random secrets:

secrets:
  # Basic password
  - name: admin-password
    type: generated
    spec:
      length: 24
      charset: alphanumeric

  # Complex password with special characters
  - name: db-password
    type: generated
    spec:
      length: 32
      charset: alphanumeric-special

  # Numeric PIN
  - name: access-code
    type: generated
    spec:
      length: 6
      charset: numeric

  # Hex string (for tokens, keys)
  - name: api-token
    type: generated
    spec:
      length: 64
      charset: hex

Character Sets:

CharsetCharactersExample
alphanumerica-zA-Z0-9K7mPx2nQw9
alphanumeric-speciala-zA-Z0-9!@#$%^&*K7m!Px@2n#
numeric0-9847291
hex0-9a-fa7f3c2e1

External Secrets

Fetch secrets from external secret managers:

secrets:
  - name: api-credentials
    type: external
    spec:
      provider: vault
      path: secret/data/myapp/production
      key: api_key

  - name: db-credentials
    type: external
    spec:
      provider: vault
      path: secret/data/databases/postgres
      # Fetch entire secret as JSON

Static Secrets

For secrets that must be specified directly (use sparingly):

secrets:
  - name: license-key
    type: static
    spec:
      value: "XXXX-YYYY-ZZZZ-1234"

Using Secrets

In Helm Values

spec:
  resources:
    secrets:
      - name: gitlab-root-password
        type: generated
        spec:
          length: 24

    helm:
      - name: gitlab
        cluster: main
        namespace: gitlab
        chart: gitlab/gitlab
        values:
          global:
            initialRootPassword:
              secret: gitlab-initial-password
              key: password

Then create the Kubernetes secret:

    manifests:
      - name: gitlab-password-secret
        cluster: main
        namespace: gitlab
        template: |
          apiVersion: v1
          kind: Secret
          metadata:
            name: gitlab-initial-password
          type: Opaque
          stringData:
            password: "{{ .Resources.secrets.gitlab-root-password.value }}"

In Kubernetes Manifests

spec:
  resources:
    secrets:
      - name: api-key
        type: generated
        spec:
          length: 32
          charset: hex

    manifests:
      - name: app-secrets
        cluster: main
        template: |
          apiVersion: v1
          kind: Secret
          metadata:
            name: app-secrets
          type: Opaque
          stringData:
            API_KEY: "{{ .Resources.secrets.api-key.value }}"
          ---
          apiVersion: apps/v1
          kind: Deployment
          metadata:
            name: myapp
          spec:
            template:
              spec:
                containers:
                  - name: app
                    envFrom:
                      - secretRef:
                          name: app-secrets

In VM Cloud-Init

spec:
  resources:
    secrets:
      - name: ssh-key
        type: external
        spec:
          provider: vault
          path: secret/data/ssh/training
          key: private_key

    vms:
      - name: bastion
        provider: hetzner
        type: cx21
        userData: |
          #cloud-config
          write_files:
            - path: /root/.ssh/id_rsa
              permissions: '0600'
              content: |
                {{ .Resources.secrets.ssh-key.value | indent 16 }}

Per-Participant Secrets

Generate unique secrets for each participant:

spec:
  variables:
    - name: participant_count
      type: integer
      default: 10

  resources:
    secrets:
      - name: "participant-{{ .Index }}-password"
        type: generated
        count: "{{ .Variables.participant_count }}"
        spec:
          length: 16
          charset: alphanumeric

    manifests:
      - name: participant-secrets
        cluster: main
        count: "{{ .Variables.participant_count }}"
        template: |
          apiVersion: v1
          kind: Secret
          metadata:
            name: participant-credentials
            namespace: participant-{{ .Index }}
          type: Opaque
          stringData:
            password: "{{ (index .Resources.secrets (printf "participant-%d-password" .Index)).value }}"

Secret Outputs

Access secret values in templates:

# Reference secret value
{{ .Resources.secrets.my-secret.value }}

# Reference with index (for counted secrets)
{{ (index .Resources.secrets "participant-0-password").value }}

# Dynamic index
{{ (index .Resources.secrets (printf "participant-%d-password" .Index)).value }}

Available secret outputs:

OutputDescription
.valueThe secret value
.nameSecret name
.typeSecret type (generated, external, static)
.lengthLength (for generated secrets)

Common Patterns

Database Credentials

spec:
  resources:
    secrets:
      - name: postgres-password
        type: generated
        spec:
          length: 32
          charset: alphanumeric

    helm:
      - name: postgresql
        cluster: main
        namespace: database
        chart: bitnami/postgresql
        values:
          auth:
            postgresPassword: "{{ .Resources.secrets.postgres-password.value }}"
            database: myapp

TLS Certificates

For external certificates:

secrets:
  - name: tls-cert
    type: external
    spec:
      provider: vault
      path: secret/data/certs/wildcard
      key: certificate

  - name: tls-key
    type: external
    spec:
      provider: vault
      path: secret/data/certs/wildcard
      key: private_key

Then use in Kubernetes:

manifests:
  - name: tls-secret
    cluster: main
    namespace: ingress-nginx
    template: |
      apiVersion: v1
      kind: Secret
      metadata:
        name: wildcard-tls
      type: kubernetes.io/tls
      stringData:
        tls.crt: |
          {{ .Resources.secrets.tls-cert.value | indent 10 }}
        tls.key: |
          {{ .Resources.secrets.tls-key.value | indent 10 }}

GitLab Runner Registration

spec:
  resources:
    secrets:
      - name: runner-token
        type: external
        spec:
          provider: vault
          path: secret/data/gitlab/runners
          key: registration_token

    vms:
      - name: runner
        provider: hetzner
        type: cx31
        userData: |
          #cloud-config
          runcmd:
            - |
              gitlab-runner register 
                --non-interactive 
                --url "https://gitlab.{{ .Environment.Domain }}" 
                --registration-token "{{ .Resources.secrets.runner-token.value }}" 
                --executor docker 
                --docker-image alpine:latest

OAuth/API Keys

spec:
  resources:
    secrets:
      - name: github-oauth-id
        type: external
        spec:
          provider: vault
          path: secret/data/oauth/github
          key: client_id

      - name: github-oauth-secret
        type: external
        spec:
          provider: vault
          path: secret/data/oauth/github
          key: client_secret

    helm:
      - name: gitlab
        values:
          global:
            appConfig:
              omniauth:
                providers:
                  - secret: gitlab-oauth-secrets

External Provider Configuration

HashiCorp Vault

Configure Vault access at the organization level:

# Organization settings (not in blueprint)
secrets:
  vault:
    address: https://vault.example.com
    auth:
      method: kubernetes
      role: teabar-reader
    # Or with token
    auth:
      method: token
      token: hvs.xxx  # From environment variable

Blueprint usage:

secrets:
  - name: my-secret
    type: external
    spec:
      provider: vault
      path: secret/data/myapp/config
      key: api_key

AWS Secrets Manager

# Organization settings
secrets:
  aws:
    region: us-east-1
    # Uses IAM role or environment credentials

Blueprint usage:

secrets:
  - name: rds-password
    type: external
    spec:
      provider: aws-secrets-manager
      path: prod/rds/master
      key: password

Azure Key Vault

# Organization settings
secrets:
  azure:
    tenantId: xxx-xxx-xxx
    # Uses managed identity or service principal

Blueprint usage:

secrets:
  - name: storage-key
    type: external
    spec:
      provider: azure-keyvault
      vault: my-keyvault
      path: storage-connection-string

Security Best Practices

Never Commit Static Secrets

# Bad: Secret in blueprint
secrets:
  - name: api-key
    type: static
    spec:
      value: "sk_live_abc123"  # Don't do this!

# Good: Use external provider
secrets:
  - name: api-key
    type: external
    spec:
      provider: vault
      path: secret/data/api-keys
      key: stripe

# Good: Generate at runtime
secrets:
  - name: api-key
    type: generated
    spec:
      length: 32

Use Appropriate Character Sets

# Database passwords - avoid special chars that break connection strings
secrets:
  - name: db-password
    type: generated
    spec:
      length: 32
      charset: alphanumeric  # Safe for URLs and connection strings

# API tokens - hex is URL-safe
secrets:
  - name: api-token
    type: generated
    spec:
      length: 64
      charset: hex

Limit Secret Scope

Create secrets only where needed:

# Create in specific namespace
manifests:
  - name: app-secret
    cluster: main
    namespace: myapp  # Not in default namespace
    template: |
      apiVersion: v1
      kind: Secret
      # ...

Rotate Generated Secrets

Generated secrets are unique per environment. When you need rotation:

# Destroy and recreate environment
teactl env delete my-env
teactl env create -f blueprint.yaml --name my-env

Troubleshooting

Secret Not Available

If a secret reference fails:

# Check secret was created
teactl env secrets list my-env

# View secret metadata (not value)
teactl env secrets get my-env/db-password

External Secret Fetch Failed

Check provider connectivity:

# Test Vault connection
teactl secrets test vault --path secret/data/test

# Test AWS Secrets Manager
teactl secrets test aws-secrets-manager --path test/secret

Related Resources

ende