Files
Gabriel Brown 89761a7da3 Keep the personal half of the desktop in one place, and ask before installing it
Agent instructions, skills, SSH host aliases and expansion triggers are worth
having identical on every machine one person owns, and belong in none of the
shared configuration. They live in user/ now, with a manifest saying where each
piece goes and a link-user stage that puts it there.

That stage does nothing unless the machine said yes. Somebody who clones Panama
to try the desktop keeps their own ~/.claude/CLAUDE.md exactly where it was;
the question names the destinations and defaults to no. Anything displaced goes
to config/old rather than being deleted.

~/.claude/CLAUDE.md and ~/.codex/AGENTS.md were byte-identical copies of one
file, which is the drift this exists to prevent.

Also adds the vitals toggles for the battery and Claude usage readouts, which
had preferences and no way to reach them.
2026-08-22 08:54:43 -04:00

6.0 KiB
Raw Permalink Blame History

Kubernetes Operator

The Infisical Secrets Operator syncs secrets from Infisical into Kubernetes Secrets, so pods can consume them as env vars or volume mounts without application-level SDK integration.

Supported versions

Kubernetes: 1.29 1.33. Distributions: EKS, GKE, AKS, OKE, OpenShift.

Installation

# Add the Helm repo
helm repo add infisical-helm-charts 'https://dl.cloudsmith.io/public/infisical/helm-charts/helm/charts/'
helm repo update

# Cluster-wide install
helm install --generate-name infisical-helm-charts/secrets-operator

# Namespace-scoped install (if you want to limit the operator's reach)
helm install operator-namespaced infisical-helm-charts/secrets-operator \
  --namespace my-namespace \
  --set scopedNamespaces=my-namespace \
  --set scopedRBAC=true

Connecting to Infisical

By default the operator talks to https://app.infisical.com/api. For self-hosted instances, configure via ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
  name: infisical-config
  namespace: infisical-operator-system
data:
  hostAPI: https://your-instance.com/api

For in-cluster Infisical: http://<service-name>.<namespace>.svc.cluster.local:4000/api

For custom/self-signed CA certificates:

data:
  hostAPI: https://your-instance.com/api
  tls.caRef.secretName: custom-ca-certificate
  tls.caRef.secretNamespace: default
  tls.caRef.key: ca.crt

CRD 1: InfisicalSecret (pull secrets into K8s)

This is the most common use case — syncing secrets from Infisical into a Kubernetes Secret.

Step 1: Create auth credentials

kubectl create secret generic universal-auth-credentials \
  --from-literal=clientId="<your-client-id>" \
  --from-literal=clientSecret="<your-client-secret>"

Important: The user should create their own machine identity and credentials in the Infisical dashboard. Never generate these on their behalf.

Step 2: Create the InfisicalSecret resource

apiVersion: secrets.infisical.com/v1alpha1
kind: InfisicalSecret
metadata:
  name: my-app-secrets
spec:
  hostAPI: https://app.infisical.com/api
  syncConfig:
    resyncInterval: 60s
    instantUpdates: false

  authentication:
    universalAuth:
      secretsScope:
        projectSlug: my-project
        envSlug: prod
        secretsPath: "/"
      credentialsRef:
        secretName: universal-auth-credentials
        secretNamespace: default

  managedKubeSecretReferences:
    - secretName: my-app-managed-secret
      secretNamespace: default
      creationPolicy: "Orphan"

Step 3: Use in your deployment

envFrom:
  - secretRef:
      name: my-app-managed-secret

Auth methods for Kubernetes

Universal Auth (shown above) — simplest, works anywhere.

Kubernetes Auth (recommended for K8s) — zero-secret, uses pod service account tokens:

  1. Create a token reviewer service account with system:auth-delegator role
  2. Create a service account for your workload
  3. Configure the identity with Kubernetes Auth in the Infisical dashboard
  4. Reference in the CRD:
authentication:
  kubernetesAuth:
    identityId: <identity-id>
    secretsScope:
      projectSlug: my-project
      envSlug: prod
      secretsPath: "/"
    serviceAccountRef:
      name: my-service-account
      namespace: default

With autoCreateServiceAccountToken: true, the operator handles token lifecycle automatically.

Resync interval

  • Default: 1 minute (if instantUpdates=false), 1 hour (if instantUpdates=true)
  • Minimum: 5 seconds
  • Format: [number][unit]s, m, h, d, w

Templating

Use Go templates with Sprig functions to transform secrets:

managedKubeSecretReferences:
  - secretName: my-tls-secret
    secretNamespace: default
    template:
      data:
        tls.crt: "{{ .secrets.TLS_CERT | b64dec }}"
        tls.key: "{{ .secrets.TLS_KEY | b64dec }}"

CRD 2: InfisicalPushSecret (push K8s secrets to Infisical)

Pushes secrets from Kubernetes into Infisical — useful for bootstrapping or migration.

apiVersion: secrets.infisical.com/v1alpha1
kind: InfisicalPushSecret
metadata:
  name: push-to-infisical
spec:
  resyncInterval: 1m
  hostAPI: https://app.infisical.com/api
  updatePolicy: Replace   # None (skip if exists) or Replace (overwrite)
  deletionPolicy: Delete  # None (leave in Infisical) or Delete (remove when CRD deleted)

  destination:
    projectId: <project-id>
    environmentSlug: prod
    secretsPath: /

  push:
    secret:
      secretName: my-k8s-secret
      secretNamespace: default

  authentication:
    universalAuth:
      credentialsRef:
        secretName: universal-auth-credentials
        secretNamespace: default

CRD 3: InfisicalDynamicSecret (dynamic secret leases)

Generates short-lived credentials (e.g., database passwords) and syncs them to K8s:

apiVersion: secrets.infisical.com/v1alpha1
kind: InfisicalDynamicSecret
metadata:
  name: dynamic-db-creds
spec:
  hostAPI: https://app.infisical.com/api

  dynamicSecret:
    secretName: postgres-dynamic
    projectId: <project-id>
    secretsPath: /
    environmentSlug: prod

  leaseRevocationPolicy: Revoke  # Revoke lease when CRD is deleted
  leaseTTL: 30m                  # Max 24h

  managedSecretReference:
    secretName: db-credentials
    secretNamespace: default
    creationPolicy: Orphan

  authentication:
    universalAuth:
      credentialsRef:
        secretName: universal-auth-credentials
        secretNamespace: default

The operator automatically rotates the lease before expiration.

Monitoring

The operator exposes Prometheus metrics. Enable ServiceMonitor:

# In Helm values
telemetry:
  serviceMonitor:
    enabled: true
    interval: 30s

Key metrics: controller_runtime_reconcile_total, controller_runtime_reconcile_errors_total, controller_runtime_reconcile_time_seconds.

Troubleshooting

Check the status of an InfisicalSecret:

kubectl get infisicalsecret my-app-secrets -o yaml

Look at status.conditions for error details. Common issues: wrong project slug, missing permissions on the machine identity, credentials secret not found.