Secrets
Overview
Abschnitt betitelt „Overview“Greentic treats secrets as runtime data, not pack data. Packs and components declare the credentials they need, but secret values are supplied during setup and resolved through a configured secrets backend at runtime.
This separation matters because the same digital worker can run for many tenants and teams. Each tenant can use the same application pack while receiving different Slack tokens, OpenAI keys, webhook signing secrets, OAuth client credentials, database credentials, or API keys.
The model has four parts:
| Layer | Responsibility |
|---|---|
| Component or pack | Declares required secret keys, formats, descriptions, and optional scope hints. |
gtc setup / greentic-secrets | Collects, validates, imports, and writes secret values. |
| Secrets backend or extension | Stores and resolves secret material. |
| Runtime host | Enforces tenant scope, capability grants, redaction, and audit/telemetry metadata. |
Secret Requirements
Abschnitt betitelt „Secret Requirements“Components and packs declare secret requirements using the canonical Greentic secret types from greentic-types and greentic-interfaces.
The current shared shape is:
pub struct SecretRequirement { pub key: SecretKey, pub required: bool, pub description: Option<String>, pub scope: Option<SecretScope>, pub format: Option<SecretFormat>, pub schema: Option<serde_json::Value>, pub examples: Vec<String>,}The matching WIT package is greentic:secrets-types@1.0.0. Its secret-requirement record contains the logical key, whether it is required, an optional operator-facing description, optional environment/tenant/team scope, optional format, optional schema, and examples.
Secret keys are validated. They must be non-empty, use only ASCII letters, digits, ., _, -, and /, must not start with /, and must not contain a .. path segment.
Example component manifest excerpt:
{ "secret_requirements": [ { "key": "openai/api_key", "required": true, "description": "API key used by the research analyst component", "scope": { "env": "prod", "tenant": "acme", "team": "research" }, "format": "text" } ], "capabilities": { "host": { "secrets": { "required": [ { "key": "openai/api_key", "required": true, "format": "text" } ] } } }}Greentic component tooling writes secret_requirements and mirrors the same requirements into capabilities.host.secrets.required. The runtime uses those declarations to deny undeclared secret access.
Runtime Access
Abschnitt betitelt „Runtime Access“Secrets are accessed through the secrets host capability. They are not injected into JSON operation payloads and should not be templated into flow definitions.
The current WIT host surfaces are:
| Interface | Purpose |
|---|---|
greentic:secrets-store@1.0.0 | Read-only get(key) interface. |
greentic:secrets-store@1.1.0 | Read/write interface with get(key) and put(key, value). |
greentic:secrets-types@1.0.0 | Shared metadata types for secret requirements, scopes, and formats. |
The component receives a tenant-aware invocation context from the host. The host combines that context with the declared requirement and the configured backend. A component should ask for a logical key such as openai/api_key; it should not build raw vault paths or encode tenant ids into ad hoc strings.
Multi-Tenant Scope
Abschnitt betitelt „Multi-Tenant Scope“Secret resolution is scoped by TenantCtx. The canonical scope is:
env + tenant + optional team + logical keySetup flows and demos use tenant-aware secret URIs such as:
secrets://{env}/{tenant}/{team}/{provider}/{key}Examples:
secrets://prod/acme/_/slack/bot_tokensecrets://prod/acme/research/openai/api_keysecrets://dev/demo/_/telegram/bot_tokenThe _ segment is commonly used when no team is selected. The important rule is that tenant and team are part of the lookup boundary. A secret for tenant acme must not satisfy a request for tenant globex, even when both tenants use the same app pack and the same logical key.
For platform-level services, use a clearly separate scope and key namespace. For example, repo infrastructure can use paths such as:
repo/{env}/{tenant}/{team_or_underscore}/signing/buildrepo/{env}/{tenant}/{team_or_underscore}/http/runner/bearerThat keeps platform credentials distinct from application and messaging credentials.
Secrets Backends
Abschnitt betitelt „Secrets Backends“Greentic configuration stores only the backend selector and reference:
[secrets]kind = "none"reference = "..."The default kind is none, which is appropriate only when the active workload has no runtime secret needs. Production deployments should use a real secrets manager through the runtime, deployer, or a secrets extension pack.
Common backend choices include:
| Backend style | Typical use |
|---|---|
| Local/dev store | Fast local demos, tests, and isolated development. |
greentic-secrets broker/store | Greentic-managed setup/import flow and tenant-aware secret writing. |
| AWS Secrets Manager | AWS deployments and AWS-native credential policy. |
| Azure Key Vault | Azure deployments and Azure-native identity/policy. |
| Google Secret Manager | Google Cloud deployments and GCP-native IAM. |
| HashiCorp Vault | Self-managed or cross-cloud vault operations. |
| Kubernetes or container secrets | Runtime injection for custom deployers where the deployer maps Greentic requirements into cluster/container-native secrets. |
The bundle wizard catalog currently includes AWS Secrets Manager entries for Greentic secrets extension packs. Other managers should be wired through the same extension/backend pattern: the pack advertises the capability and setup requirements, while the deployment/runtime chooses the actual backend implementation.
Setup Workflow
Abschnitt betitelt „Setup Workflow“Use setup tooling to populate secrets instead of editing files by hand.
gtc setup --bundle ./bundlegtc setup detects the bundle tenant from tenants/, asks for required credentials, writes values into the configured secrets store, and validates required capabilities across the bundle.
For lower-level secret workflows, use greentic-secrets:
greentic-secrets scaffold --pack ./my-pack.gtpack --out ./secrets.answers.jsongreentic-secrets wizard --input ./secrets.answers.json --output ./secrets.filled.jsongreentic-secrets apply --file ./secrets.filled.jsonUseful greentic-secrets commands include:
| Command | Purpose |
|---|---|
greentic-secrets scaffold | Create an answer document from pack secret requirements. |
greentic-secrets wizard | Fill or import secret answers, including from .env for local workflows. |
greentic-secrets apply | Write filled answers into the selected store/broker. |
greentic-secrets init | Scaffold and apply secrets for a pack in one flow. |
greentic-secrets config show | Inspect the effective secrets configuration. |
greentic-secrets config explain | Explain where the CLI is reading its configuration from. |
Component Development
Abschnitt betitelt „Component Development“When creating a component, use the wizard or CLI flags to declare secret requirements:
greentic-component wizard apply --mode create \ --answers ./component-create-answers.jsonFor local testing, greentic-component test can load declared secrets from:
greentic-component test ./component.wasm \ --secrets ./secrets.envIt also supports JSON maps and repeated inline values:
greentic-component test ./component.wasm \ --secrets-json ./secrets.json \ --secret openai/api_key=sk-local-testThe local harness denies access to secrets that are not declared in the component manifest. That behavior is intentional: it catches missing capability declarations before the component reaches a shared runtime.
Rotation And Missing Secrets
Abschnitt betitelt „Rotation And Missing Secrets“Secret rotation should be handled by updating the backend value and rerunning setup or deployment validation. gtc setup is idempotent: rerunning it can overwrite existing values in place and rerun provider-specific setup flows.
For operations, prefer fail-fast checks. Selected packs should aggregate their secret_requirements before execution and report missing secrets with a remediation path, such as:
greentic-secrets init --pack ./my-pack.gtpackObservability And Redaction
Abschnitt betitelt „Observability And Redaction“Secret operations should be observable without exposing secret values. Telemetry may record metadata such as:
| Attribute | Meaning |
|---|---|
secrets.op | get, put, delete, or list. |
secrets.key | Logical secret key. Never the value. |
secrets.scope.env | Environment scope. |
secrets.scope.tenant | Tenant scope. |
secrets.scope.team | Optional team scope. |
secrets.result | ok, not_found, denied, invalid, or error. |
Logs, traces, and inspector output must redact values with names such as secret, token, api_key, authorization, password, client_secret, access_token, refresh_token, bearer, and x-api-key.
Secrets-related events should carry metadata only. Events such as greentic.secrets.put, greentic.secrets.delete, greentic.secrets.rotate.requested, greentic.secrets.rotate.completed, and greentic.secrets.missing.detected must never include secret bytes, even if encoded.
Deployment Checklist
Abschnitt betitelt „Deployment Checklist“- Declare every required credential as a
SecretRequirement. - Keep secret values out of packs, bundles, flows, cards, source code, and committed setup answers.
- Choose a real backend for production instead of
kind = "none". - Scope secrets by environment, tenant, and team.
- Use
gtc setuporgreentic-secretsto populate values. - Validate missing secrets before starting runtime traffic.
- Configure redaction before exporting logs or traces.
- Rotate backend values and rerun setup/deployment validation after rotation.