跳转到内容

Secrets in Environments

此内容尚不支持你的语言。

The Secrets concept page covers how packs and components declare the credentials they need, how the runtime resolves and isolates them, and how redaction works. This page focuses on the operator side: supplying secret values to a deployed environment, choosing a backend, and scoping credentials by tenant and team.

Greentic uses two URI forms for secrets. The distinction matters when you write manifests and endpoint configurations.

Store URI — the full five-segment address used internally by the secrets store:

secrets://<env>/<tenant>/<team>/<category>/<name>

The category segment is typically the provider or pack identifier, such as messaging-telegram or openai. An optional @version suffix pins a specific version of the secret.

Reference form — the shorter form used in manifests and endpoint secret_refs:

secret://<env>/<tenant>/<team>/<category>/<name>

The reference form converts to the store URI internally. You will encounter the secret:// form in environment manifests and messaging endpoint configurations.

Team segment normalization: the values _, empty, and default all normalize to _, meaning tenant-scoped. A secret stored at the tenant level (with _ as the team) serves all teams under that tenant unless a team-specific secret overrides it.

Fallback behavior: when the runtime looks up a secret with a specific team scope and finds nothing, it automatically retries with the tenant-level (_) URI. This lets you store a credential once at the tenant level while still allowing per-team overrides where needed.

Allowed characters: all segments use [a-z0-9-_.]. Names are normalized to lowercase with separators converted to underscores.

Environment-variable projection: a store URI can also be satisfied from a process environment variable. The derived variable name follows the pattern GREENTIC_SECRET__<ENV>__<TENANT>__<TEAM>__<CATEGORY>__<NAME>. A read-only env backend variant uses the pattern GTSEC_<ENV>_<TENANT>_<TEAM>_<CATEGORY>_<NAME>.

There are three ways to get secret values into an environment. In all cases, the values themselves never appear in committed files.

The secrets[] section of an environment manifest lists secrets by path. Each entry names the secret’s store path and optionally the environment variable to read the value from at apply time:

"secrets": [
{
"path": "default/_/messaging-telegram/telegram_bot_token",
"from_env": "TELEGRAM_BOT_TOKEN"
},
{
"path": "default/_/openai/api_key"
}
]

When from_env is present, gtc op env apply reads the value from that environment variable at apply time. When from_env is absent, the operator is prompted for a masked interactive paste.

Running gtc setup --env <name> walks you through each required secret. For each secret, you choose whether to supply an environment variable name or paste the value directly (input is masked).

For ad-hoc secret management outside of manifest applies or wizard runs:

Terminal window
gtc op secrets list
gtc op secrets put --answers secrets-payload.json
gtc op secrets get --answers query-payload.json
gtc op secrets rotate --answers rotate-payload.json

These commands accept payloads through the --answers flag.

The development store is a plaintext, file-backed store located under the environment or bundle directory. It requires no configuration and is the default when no backend is bound to the environment. It is appropriate for local development and demos only. For production, bind a real secrets backend through the environment’s secrets capability slot.

BackendProvider IDMain config knobsNotes
Dev storegreentic.secrets.dev-storeNoneLocal plaintext; default when nothing is configured
Env vars (read-only)envGTSEC_* variablesRead-only; requires GREENTIC_ALLOW_ENV_SECRETS=1
AWS Secrets Managergreentic.secrets.aws-smGREENTIC_AWS_KMS_KEY_ID (required), GREENTIC_AWS_REGION, GREENTIC_AWS_SECRET_PREFIXDefault prefix gtsec; names are slash paths
Azure Key Vaultgreentic.secrets.azure-kvVault URL + Azure identity127-char name limit; names folded with hash suffix
GCP Secret Managergreentic.secrets.gcp-smGCP project + identity255-char name limit; names folded with hash suffix
HashiCorp Vaultgreentic.secrets.vault-kvVAULT_ADDR (required); token or K8s workload identity authKV v2 + Transit; TLS verification cannot be disabled
Kubernetes Secretsgreentic.secrets.k8sIn-cluster identityPreview — early-stage

Requires a KMS key (GREENTIC_AWS_KMS_KEY_ID). Secret names are stored as slash-separated paths under a configurable prefix: <prefix>/<env>/<tenant>/<team>/<category>/<name>, where the default prefix is gtsec. Configure the region with GREENTIC_AWS_REGION and override the prefix with GREENTIC_AWS_SECRET_PREFIX.

Requires VAULT_ADDR. Authenticate with either a VAULT_TOKEN or Kubernetes workload identity (VAULT_K8S_ROLE, VAULT_K8S_JWT_PATH, VAULT_K8S_MOUNT). Secrets are stored as slash paths under the KV v2 mount (VAULT_KV_MOUNT, default secret) with a configurable prefix (VAULT_KV_PREFIX, default greentic). Transit encryption is available via VAULT_TRANSIT_MOUNT and VAULT_TRANSIT_KEY. Namespace isolation uses VAULT_NAMESPACE. A custom CA bundle can be set with VAULT_CA_BUNDLE, but TLS verification cannot be disabled.

Both backends fold secret names to comply with their respective character restrictions. Azure Key Vault limits names to [0-9a-z-] and 127 characters. GCP Secret Manager allows [a-zA-Z0-9_-] up to 255 characters. Both append a 16-character hex hash suffix to preserve uniqueness when names are folded. The readable portion of a long name is truncated to make room for the suffix.

The secrets backend for an environment is set through a JSON binding document:

secrets-binding.json
{
"schema_version": "greentic.secrets.binding.v1",
"provider_id": "greentic.secrets.aws-sm",
"pack": "providers/secrets/aws-sm.gtpack",
"config": {
"namespace_prefix": "greentic",
"region": "eu-north-1",
"environment": "prod"
}
}

This binding lives in the environment’s platform configuration. At the environment manifest level, the same concept is expressed as an entry in the packs[] section with "slot": "secrets":

"packs": [
{
"slot": "secrets",
"kind": "greentic.secrets.aws-sm@1.0.0",
"pack_ref": "builtin"
}
]

Both forms select which secrets backend the environment uses. Swapping the backend does not require redeploying application bundles — bundles reference secrets by logical name, and the runtime resolves them through whatever backend is bound.

The runtime selects a secrets-manager pack by searching in this order:

  1. GREENTIC_SECRETS_MANAGER_PACK environment variable (absolute or bundle-relative path) — unconditional override.
  2. <bundle_root>/providers/secrets/<tenant>/<team>/*.gtpack — team-specific pack.
  3. <bundle_root>/providers/secrets/<tenant>/*.gtpack — tenant-specific pack.
  4. <bundle_root>/providers/secrets/*.gtpack — bundle default.
  5. Nothing found — falls back to the dev store.

Stick to lowercase letters, digits, hyphens, and underscores in tenant, team, category, and secret name segments. This keeps names portable across all backends.

BackendCharacter setMax lengthBehavior
AWS Secrets ManagerSlash paths round-trip exactlyLiberalNames stored as-is under the prefix
HashiCorp VaultSlash paths round-trip exactlyLiberalNames stored as-is under the KV mount
Azure Key Vault[0-9a-z-]127 charsFolded + hash suffix; long names truncated
GCP Secret Manager[a-zA-Z0-9_-]255 charsFolded + hash suffix; long names truncated
KubernetesLabel-safeNamespace-scopedPreview

Azure Key Vault’s 127-character limit is the tightest constraint. If you use long tenant names or deeply nested categories, the readable portion of the secret name will be truncated to make room for the uniqueness hash. Prefer short, descriptive names.