Create
A resource names a provider (random, cloudflare, tailscale, …) and its settings. tegata apply creates what does not exist yet.
tegata creates secrets (random keys, API tokens for services such as Cloudflare and Tailscale, database passwords), stores them in a cloud secret store, gives each server or application read access to exactly the secrets you list for it, rotates them, cleans up the old ones, and fills in configuration templates on the servers.
Everything is declared in one YAML file. No server to run, no Kubernetes required.
Cloud secret stores and Vault-style servers are good at storing secrets. Rotating secrets that belong to other services is usually left to you: write a rotation function per service, or do it by hand in each dashboard. tegata puts the whole lifecycle in one place:
Create
A resource names a provider (random, cloudflare, tailscale, …) and its settings. tegata apply creates what does not exist yet.
Store and grant
Values go to Secret Manager. Each secret names its readers (identities: the service accounts of servers, applications, CI workflows), and only they can read it.
Rotate and clean up
tegata rotate makes a new generation; after the servers pick it up, tegata prune deletes what the provider created for older generations (for example, the old API token) and disables the old versions.
Fill in
On a server, tegata render replaces __NAME__ in templates with the stored values.
Deliver
Copies of secrets can also go to GitHub Actions secrets (of a repository or an environment). tegata writes them again whenever the value changes, so CI picks up a rotation on its next run.
Providers are separate executables that speak JSON over stdin and stdout, so you can add one in any language without changing tegata.
To try it on your machine without a cloud account, see examples/minimal.
stores: main: gcp: project: my-project location: us-central1 # where secret replicas live (user-managed replication)
identities: # who reads secrets: names for IAM members app: [serviceAccount:app-vm@my-project.iam.gserviceaccount.com]
providers: # external providers (random, manual and value are built in) cloudflare: source: github.com/k-kawa/tegata # installed by `tegata init` version: "^0.3" config: { account_id: 0123456789abcdef } credentials: # never write secrets in the YAML api_token: { env: TEGATA_CLOUDFLARE_TOKEN }
resources: session_key: provider: random config: { bytes: 32 } stores: main: # where it is stored, under what name, and who reads it - { name: SESSION_KEY, readers: [app] } previous: { name: PREVIOUS_SESSION_KEY } # rotate copies the current value here first releases_read: provider: cloudflare type: api_token config: name: releases read policies: - permissions: [Workers R2 Storage Bucket Item Read] r2_buckets: [releases] stores: main: # one entry per provider output - { output: id, name: RELEASES_ACCESS_KEY_ID, readers: [app] } - { output: r2_secret_access_key, name: RELEASES_SECRET_ACCESS_KEY, readers: [app] }SESSION_KEY=__SESSION_KEY__PREVIOUS_SESSION_KEY=__PREVIOUS_SESSION_KEY__RELEASES_ACCESS_KEY_ID=__RELEASES_ACCESS_KEY_ID__RELEASES_SECRET_ACCESS_KEY=__RELEASES_SECRET_ACCESS_KEY__tegata init # install the providers, pinned in tegata.locktegata check app templates/app # providers, and app can read every name in templates/apptegata apply # containers, read access, missing valuestegata status # generations, enabled versions, readers
# on the server (no YAML needed; on GCP VMs the project comes from the metadata server)tegata render templates/app /etc/appRotating a key:
tegata rotate session_key # new generation; the old value moves to PREVIOUS_SESSION_KEY# ... re-run `tegata render` on the servers and restart the services ...tegata settle session_key # PREVIOUS_SESSION_KEY = SESSION_KEY (the old value is no longer accepted)tegata prune session_key # disable the old versions| Provider | Types | What it makes |
|---|---|---|
random (built in) |
Random bytes as hex (bytes, default 32) |
|
manual (built in) |
A value you type in (tegata set) |
|
value (built in) |
data | Fixed, non-secret values written in the YAML |
tegata-provider-cloudflare |
api_token, tunnel_token |
Account API tokens (also usable as R2 keys), Tunnel tokens |
tegata-provider-tailscale |
auth_key |
Auth keys for joining a tailnet |
tegata-provider-aws |
ses_smtp_credentials |
Amazon SES SMTP credentials (an access key for an IAM user) |
tegata-provider-gcp |
sql_user |
Cloud SQL built-in user passwords |
tegata-provider-terraform |
outputs (data) |
Values read from Terraform outputs |
Settings, outputs, and rotation behavior of each: providers. Writing a provider: the provider protocol.
Functional Source License, Version 1.1, ALv2 Future License (FSL-1.1-ALv2).
In short: you can use, modify, and redistribute tegata for any purpose except offering it to others as a commercial product or service that competes with it. Using tegata inside your company, for your own infrastructure, or in professional services for your clients is fine. Each version becomes available under the Apache License 2.0 two years after it is released.
FSL is a Fair Source license, not an OSI-approved open source license. If your organization only allows OSI-approved licenses, check with them before using tegata.