Skip to content

Commit 6c4b234

Browse files
committed
Add external secret providers
1 parent 7fb1754 commit 6c4b234

12 files changed

Lines changed: 485 additions & 73 deletions

File tree

README.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -303,8 +303,8 @@ Variables are external and can be overridden by CLI:
303303
automax run --job job.yaml --inventory inventory.yaml --vars vars.yaml --var app_version=2.1.0
304304
```
305305

306-
Secrets support `env`, `file` and `command`, and the provider interface
307-
remains pluggable.
306+
Secrets support local sources and common external secret managers through
307+
controller-side providers.
308308

309309
```yaml
310310
secrets:
@@ -317,9 +317,15 @@ secrets:
317317
path: ~/.ssh/id_ed25519.path
318318
319319
deploy_token:
320-
provider: command
321-
command: ["pass", "show", "prod/automax/deploy-token"]
322-
timeout: 10
320+
provider: vault
321+
path: secret/prod/app
322+
field: deploy_token
323+
324+
db_password:
325+
provider: aws_secrets_manager
326+
secret_id: prod/db
327+
json_key: password
328+
region: eu-west-1
323329
```
324330

325331
Dynamic inventory providers are available when targets come from a generated file,

docs/TECHNICAL_DESIGN.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,10 @@ automax run \
5151

5252
## Secrets
5353

54-
The first implementation supports only `env` and `file` providers. The provider
55-
interface remains pluggable so Vault, AWS Secrets Manager, Azure Key Vault, GCP
56-
Secret Manager or other backends can be added later without changing the job DSL.
54+
Secrets are resolved on the controller through `env`, `file`, `command`,
55+
`vault`, `aws_secrets_manager`, `azure_key_vault`, `gcp_secret_manager` and
56+
`onepassword` providers. External secret manager providers use vendor CLIs so
57+
the runner does not require cloud SDK dependencies.
5758

5859
## Strategy
5960

@@ -137,7 +138,6 @@ External plugins can be loaded with `--plugin-path`.
137138

138139
## Remaining non-goals for this implementation
139140

140-
- Cloud secret providers.
141141
- Central database state backend.
142142
- Deploy-release orchestration plugins with rollback semantics.
143143
- Full Ansible-equivalent module coverage.

docs/guides/command-secrets.md

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
55

66
# Command secrets
77

8-
Automax supports `env`, `file` and `command` secret providers.
8+
Automax supports `env`, `file`, `command`, `vault`, `aws_secrets_manager`, `azure_key_vault`, `gcp_secret_manager` and `onepassword` secret providers.
99

1010
Use `provider: command` when a local helper can print a secret to stdout, for
1111
example a password-store wrapper, an internal credential helper or a local
@@ -79,3 +79,66 @@ secrets:
7979
Resolved secrets are masked before stdout, stderr, messages, structured result
8080
data and artifacts are persisted to the run state. Command provider errors do
8181
not include captured stdout or stderr to avoid leaking secret material.
82+
83+
## External secret managers
84+
85+
External secret manager providers run the vendor CLI on the Automax controller.
86+
They do not add Python SDK dependencies and do not persist resolved values.
87+
The CLI must already be installed and authenticated by the operator or runtime
88+
identity before Automax runs.
89+
90+
HashiCorp Vault:
91+
92+
```yaml
93+
secrets:
94+
deploy_token:
95+
provider: vault
96+
path: secret/prod/app
97+
field: deploy_token
98+
```
99+
100+
AWS Secrets Manager:
101+
102+
```yaml
103+
secrets:
104+
db_password:
105+
provider: aws_secrets_manager
106+
secret_id: prod/db
107+
json_key: password
108+
region: eu-west-1
109+
```
110+
111+
Azure Key Vault:
112+
113+
```yaml
114+
secrets:
115+
api_token:
116+
provider: azure_key_vault
117+
vault_name: prod-vault
118+
secret_name: automax-api-token
119+
```
120+
121+
GCP Secret Manager:
122+
123+
```yaml
124+
secrets:
125+
api_token:
126+
provider: gcp_secret_manager
127+
project: prod-project
128+
secret: automax-api-token
129+
version: latest
130+
```
131+
132+
1Password:
133+
134+
```yaml
135+
secrets:
136+
deploy_token:
137+
provider: onepassword
138+
reference: op://Production/Automax/deploy-token
139+
```
140+
141+
Each provider accepts `timeout` and `strip`. Providers that return structured
142+
JSON can use `json_key` where documented, for example AWS Secrets Manager.
143+
Use `command` or `binary` only when the vendor CLI binary is installed under a
144+
non-standard name or path.

docs/plugins/database.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ fetch: all # all, one, none
3232
commit: true # false rolls back at the end intentionally
3333
```
3434
35-
Secrets are resolved through the normal env/file secret providers before
36-
rendering:
35+
Secrets are resolved through the configured secret providers before rendering:
3736
3837
```yaml
3938
password: "{{ secrets.db_password }}"

docs/reference/future-work.md

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,12 @@ This page tracks product ideas that are intentionally not part of the current
99
implementation contract. Items listed here are not discarded; they are held
1010
until real operating experience proves the right shape.
1111

12-
## Additional secret providers
12+
## Secret handling hardening
1313

14-
Secret providers include `env`, `file` and `command`. Future providers may include:
15-
16-
```text
17-
Vault
18-
AWS Secrets Manager
19-
Azure Key Vault
20-
Google Secret Manager
21-
pass
22-
1Password
23-
```
24-
25-
These should be core secret providers, not job-action plugins, so secrets remain
26-
resolved before templating and execution.
14+
Secret values are resolved on the controller and masked before persisted output.
15+
Future hardening can focus on rotation workflows, provider-specific diagnostics
16+
and optional policy rules that restrict which providers may be used in selected
17+
environments.
2718

2819
## Additional schema and output formats
2920

docs/reference/inventory-vars-secrets.md

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,10 @@ automax run --job job.yaml --inventory inventory.yaml --var version=1.2.4
8888

8989
## Secrets
9090

91-
Secrets support `env`, `file` and `command` providers. The secret
92-
provider interface is intentionally pluggable so Vault, cloud secret managers or
93-
other providers can be added later without changing job YAML semantics.
91+
Secrets support `env`, `file`, `command`, `vault`, `aws_secrets_manager`,
92+
`azure_key_vault`, `gcp_secret_manager` and `onepassword` providers. External
93+
secret manager providers run their vendor CLI on the Automax controller and keep
94+
resolved values in memory only.
9495

9596
```yaml
9697
secrets:
@@ -103,9 +104,15 @@ secrets:
103104
path: ~/.ssh/automax-key-path
104105
105106
deploy_token:
106-
provider: command
107-
command: ["pass", "show", "prod/automax/deploy-token"]
108-
timeout: 10
107+
provider: vault
108+
path: secret/prod/app
109+
field: deploy_token
110+
111+
db_password:
112+
provider: aws_secrets_manager
113+
secret_id: prod/db
114+
json_key: password
115+
region: eu-west-1
109116
```
110117

111118
Shorthand forms are also supported:
@@ -122,7 +129,7 @@ secrets:
122129

123130
A plain string is accepted as an already-resolved secret value, but this should be
124131
reserved for local labs and examples. See [Command secrets](../guides/command-secrets.md)
125-
for generic external command integration and shell-safety guidance.
132+
for command-provider and external secret-manager guidance.
126133

127134
## Template context
128135

docs/reference/schemas.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ automax schema export --kind inventory --format=json --output inventory.schema.j
4545
The job schema covers task/step/substep structure, strategy, failure policy,
4646
retry policy, timeout controls and `errorPolicy`. The inventory schema covers
4747
static inventories and dynamic `file`, `command` and `http` provider wrappers.
48-
The secrets schema covers `env`, `file` and `command` providers.
48+
The secrets schema covers `env`, `file`, `command`, `vault`, `aws_secrets_manager`, `azure_key_vault`, `gcp_secret_manager` and `onepassword` providers.
4949

5050
The explicit `--format=json` option is part of the public CLI contract. It keeps
5151
the interface extensible for future formats such as YAML or OpenAPI-oriented

docs/reference/security.md

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ ssh:
6868
6969
## Secrets
7070
71-
Current secret providers are `env`, `file` and `command`.
71+
Secret providers are `env`, `file`, `command`, `vault`, `aws_secrets_manager`, `azure_key_vault`, `gcp_secret_manager` and `onepassword`.
7272

7373
```yaml
7474
secrets:
@@ -77,17 +77,24 @@ secrets:
7777
name: AUTOMAX_TOKEN
7878
7979
deploy_token:
80-
provider: command
81-
command: ["pass", "show", "prod/automax/deploy-token"]
82-
timeout: 10
80+
provider: vault
81+
path: secret/prod/app
82+
field: deploy_token
83+
84+
db_password:
85+
provider: aws_secrets_manager
86+
secret_id: prod/db
87+
json_key: password
88+
region: eu-west-1
8389
```
8490

8591
Resolved secret values are masked before stdout, stderr, messages, structured
8692
result data and artifacts are persisted to the run state.
8793

88-
Command secrets run on the controller. Prefer list-form commands and keep
89-
`shell: false` unless a trusted local helper explicitly needs shell features.
90-
Command provider errors intentionally do not include captured stdout or stderr.
94+
Command and external secret manager providers run on the controller. Prefer
95+
list-form commands for custom helpers and keep `shell: false` unless a trusted
96+
local helper explicitly needs shell features. Provider errors intentionally do
97+
not include captured stdout or stderr.
9198

9299
## Sudo
93100

src/automax/core/schema.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,19 @@ def _secrets_schema() -> Dict[str, Any]:
398398
"additionalProperties": False,
399399
"required": ["provider"],
400400
"properties": {
401-
"provider": {"type": "string", "enum": ["env", "file", "command"]},
401+
"provider": {
402+
"type": "string",
403+
"enum": [
404+
"env",
405+
"file",
406+
"command",
407+
"vault",
408+
"aws_secrets_manager",
409+
"azure_key_vault",
410+
"gcp_secret_manager",
411+
"onepassword",
412+
],
413+
},
402414
"name": {"type": "string"},
403415
"var": {"type": "string"},
404416
"path": {"type": "string"},
@@ -417,13 +429,33 @@ def _secrets_schema() -> Dict[str, Any]:
417429
"env": {"type": "object", "additionalProperties": True},
418430
"shell": {"type": "boolean"},
419431
"strip": {"type": "boolean"},
432+
"binary": {"type": "string"},
433+
"field": {"type": "string"},
434+
"namespace": {"type": "string"},
435+
"secret_id": {"type": "string"},
436+
"arn": {"type": "string"},
437+
"json_key": {"type": "string"},
438+
"region": {"type": "string"},
439+
"profile": {"type": "string"},
440+
"version_stage": {"type": "string"},
441+
"version_id": {"type": "string"},
442+
"vault_name": {"type": "string"},
443+
"vault": {"type": "string"},
444+
"secret_name": {"type": "string"},
445+
"version": {"type": "string"},
446+
"subscription": {"type": "string"},
447+
"project": {"type": "string"},
448+
"secret": {"type": "string"},
449+
"reference": {"type": "string"},
450+
"ref": {"type": "string"},
451+
"account": {"type": "string"},
420452
},
421453
}
422454
return {
423455
"$schema": SCHEMA_VERSION,
424456
"$id": f"{AUTOMAX_SCHEMA_ID}/secrets.schema.json",
425457
"title": "Automax Secrets",
426-
"description": "External Automax env, file and command secrets file.",
458+
"description": "External Automax secrets file.",
427459
"type": "object",
428460
"additionalProperties": False,
429461
"required": ["secrets"],

0 commit comments

Comments
 (0)