feat: declare the ssm value provider #1053

Merged
coilysiren merged 1 commit from feat/declare-ssm-provider into main 2026-08-14 04:39:32 +00:00
Owner

umbra v0.139.0 stopped shipping store-backed resolvers: env, file and literal are built in, anything else is declared by the consumer as an exec contract (umbra#286, closing umbra#283). aosguard names ssm in two guardfiles, so it declares it.

provider ssm {
    exec aws ssm get-parameter --with-decryption --output text --query "Parameter.Value" --name
}

The address is appended as the final argument, so this resolves value ssm "/forgejo/coilyco-ops/api-token" by running the same GetParameter the generated code used to make through aws-sdk-go-v2. Only stdout is read, so the token never reaches argv or the audit row.

The aws CLI is already installed in dev-base (install-common.sh), which is what this depends on instead of a linked SDK.

What changes

file change
.specgen/guardfiles/aosguard/forgejo.kdl declares provider ssm
.specgen/guardfiles/aosguard/actions.kdl declares provider ssm
.specgen/guardfiles/specverb.lock re-locked to umbra v0.139.0; 42 aws-sdk entries -> 0
docker/dev-base/full/Dockerfile SPECGEN_VERSION 0.138.0 -> 0.139.0

The driver bump rides along because the driver and the lock have to agree on the framework version.

Verified end to end, not just at build

  • aosguard builds against umbra v0.139.0
  • the aws guardfile still denies ops aws s3 ls s3://prod-tfstate-bucket on arg0 matching *tfstate*
  • 509 tests pass (test_check_yaml_strict.py skipped: ruamel missing in this environment, unrelated)
  • a live ops forgejo repo get coilyco-flight-deck umbra authenticates successfully - the bot token resolving through the declared provider rather than a linked SDK. That is the whole chain: guardfile -> exec provider -> aws CLI -> SSM -> Forgejo API.

One behaviour change worth naming

Credential resolution is now the aws CLI's rather than the SDK's, so the old ~/.aws/credentials SSO-shadow retry is gone. If a stale static key ever shadows an SSO profile again, it surfaces as an aws CLI error instead of a silent fallback. That trade was made deliberately in umbra#286 to keep vendor knowledge out of a policy-free engine.

umbra v0.139.0 stopped shipping store-backed resolvers: `env`, `file` and `literal` are built in, anything else is declared by the consumer as an exec contract (umbra#286, closing umbra#283). aosguard names `ssm` in two guardfiles, so it declares it. ```kdl provider ssm { exec aws ssm get-parameter --with-decryption --output text --query "Parameter.Value" --name } ``` The address is appended as the final argument, so this resolves `value ssm "/forgejo/coilyco-ops/api-token"` by running the same GetParameter the generated code used to make through `aws-sdk-go-v2`. Only stdout is read, so the token never reaches argv or the audit row. The aws CLI is already installed in dev-base (`install-common.sh`), which is what this depends on instead of a linked SDK. ## What changes | file | change | | --- | --- | | `.specgen/guardfiles/aosguard/forgejo.kdl` | declares `provider ssm` | | `.specgen/guardfiles/aosguard/actions.kdl` | declares `provider ssm` | | `.specgen/guardfiles/specverb.lock` | re-locked to umbra v0.139.0; **42 aws-sdk entries -> 0** | | `docker/dev-base/full/Dockerfile` | `SPECGEN_VERSION` 0.138.0 -> 0.139.0 | The driver bump rides along because the driver and the lock have to agree on the framework version. ## Verified end to end, not just at build - aosguard **builds** against umbra v0.139.0 - the aws guardfile still denies `ops aws s3 ls s3://prod-tfstate-bucket` on `arg0` matching `*tfstate*` - **509 tests pass** (`test_check_yaml_strict.py` skipped: `ruamel` missing in this environment, unrelated) - a live `ops forgejo repo get coilyco-flight-deck umbra` **authenticates successfully** - the bot token resolving through the declared provider rather than a linked SDK. That is the whole chain: guardfile -> exec provider -> aws CLI -> SSM -> Forgejo API. ## One behaviour change worth naming Credential resolution is now the aws CLI's rather than the SDK's, so the old `~/.aws/credentials` SSO-shadow retry is gone. If a stale static key ever shadows an SSO profile again, it surfaces as an aws CLI error instead of a silent fallback. That trade was made deliberately in umbra#286 to keep vendor knowledge out of a policy-free engine.
feat: declare the ssm value provider
All checks were successful
ci / aos-cli-tests (pull_request) Successful in 24s
ci / ward-doctor (pull_request) Successful in 13s
ci / gate (pull_request) Successful in 1m6s
dev-base-pr / build (pull_request) Successful in 8m30s
b5b1468487
umbra v0.139.0 stopped shipping store-backed resolvers: env, file and
literal are built in, anything else is declared by the consumer as an
exec contract (umbra#286, closes umbra#283). aosguard names `ssm` in
two guardfiles, so it declares it.

    provider ssm {
        exec aws ssm get-parameter --with-decryption --output text \
             --query "Parameter.Value" --name
    }

The address is appended as the final argument, so this resolves
`value ssm "/forgejo/coilyco-ops/api-token"` by running the same
GetParameter the generated code used to make through aws-sdk-go-v2.
Only stdout is read, so the token never reaches argv or the audit row.

The aws CLI is already installed in dev-base (install-common.sh), which
is what this now depends on instead of a linked SDK.

Dropping the SDK removes 42 aws-sdk entries from the frozen dependency
graph; the lock now pins umbra v0.139.0 with none. SPECGEN_VERSION
follows to 0.139.0, since the driver and the lock have to agree.

Verified end to end, not just at build: aosguard builds, the aws
guardfile still denies `s3 ls s3://prod-tfstate-bucket` on arg0, 509
tests pass, and a live `ops forgejo repo get` authenticates - the token
resolving through the declared provider rather than a linked SDK.

One behaviour change worth naming: credential resolution is now the aws
CLI's rather than the SDK's, so the old ~/.aws/credentials SSO-shadow
retry is gone. If a stale static key ever shadows an SSO profile again,
it surfaces as an aws CLI error instead of a silent fallback.

Co-authored-by: Kai Siren <coilysiren@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
coilysiren deleted branch feat/declare-ssm-provider 2026-08-14 04:39:32 +00:00
Author
Owner

Closing as already landed.

All four files this touches are byte-identical between main and this branch's head:

  • .specgen/guardfiles/aosguard/actions.kdl - main already has the provider ssm block
  • .specgen/guardfiles/aosguard/forgejo.kdl - same
  • .specgen/guardfiles/specverb.lock - main is on cliGuard v0.139.0 with zero aws-sdk-go-v2 lines remaining
  • docker/dev-base/full/Dockerfile - main already pins SPECGEN_VERSION=0.139.0

Forgejo reports this as mergeable because the merge base is stale, not because there is anything to apply. The merge would be a no-op.

Branch left in place, so this is reopenable.

Closing as already landed. All four files this touches are byte-identical between `main` and this branch's head: * `.specgen/guardfiles/aosguard/actions.kdl` - `main` already has the `provider ssm` block * `.specgen/guardfiles/aosguard/forgejo.kdl` - same * `.specgen/guardfiles/specverb.lock` - `main` is on `cliGuard v0.139.0` with zero `aws-sdk-go-v2` lines remaining * `docker/dev-base/full/Dockerfile` - `main` already pins `SPECGEN_VERSION=0.139.0` Forgejo reports this as mergeable because the merge base is stale, not because there is anything to apply. The merge would be a no-op. Branch left in place, so this is reopenable.
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
coilyco-flight-deck/agentic-os!1053
No description provided.