Skip to content

feat(pat): configure credential issuance separately from secret syncing - #151

Open
c1-squire-dev[bot] wants to merge 4 commits into
santhosh.kumar/credential-issuancefrom
c1-squire-dev/IGA-3962-split-issuance-flag
Open

feat(pat): configure credential issuance separately from secret syncing#151
c1-squire-dev[bot] wants to merge 4 commits into
santhosh.kumar/credential-issuancefrom
c1-squire-dev/IGA-3962-split-issuance-flag

Conversation

@c1-squire-dev

@c1-squire-dev c1-squire-dev Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Fifth in the stack, after #150. Splits credential issuance out of sync-secrets into its own issue-credentials flag, and documents it.

Why

sync-secrets gated four separate things: the secret and rsa_public_key syncers, the programmatic_access_token syncer, the token child-resource annotation, and the credential issuer itself. So a tenant who wanted a secret inventory had to grant the connector the ability to mint tokens to get it, and a tenant who wanted issuance had to take a full secret inventory they may not want. Neither is a choice they should be forced into.

What the flags mean now

sync-secrets issue-credentials secret types synced issuer
off off none no
on off secret, rsa_public_key, programmatic_access_token no
off on programmatic_access_token yes
on on all three yes

Independent, with one deliberate overlap: the programmatic_access_token type is synced when either flag is set. Issuance advertises CREDENTIAL_RESOURCE_MODE_DISCOVERABLE, so turning it on has to make issued tokens syncable even when the broader secret sync is off — otherwise the credential exists with nothing holding a handle to revoke it, which is the defect this stack opened by fixing. secretOptions.tokensSynced holds that rule in one place instead of repeating the disjunction at each site.

TestSecretFlagsGateIndependently pins all four rows, asserting both the advertised resource-type set and the user resource's child annotations, so the annotations cannot drift away from the types they gate.

Compatibility

Nothing regresses. Credential issuance is not on maind1a71db2 is not an ancestor of it and main's baton_capabilities.json carries no CAPABILITY_CREDENTIAL_ISSUE — so no tenant has issuance today, and sync-secrets keeps doing exactly what it does now. issue-credentials therefore defaults to off, which is the right default for a capability that mints credentials.

baton_capabilities.json is unchanged: cmd/baton-snowflake/main.go passes both flags to the default-capabilities builder, so the advertised set is the same as before.

Docs

The issuance section now names the flag and states that the two are independent. The setup step previously said only "Optional. Enable Sync secrets to display them on the Inventory page" — framed purely as display, with nothing telling a reader that issuance needed it. There is now a step for each flag.

Verification

go test ./pkg/... and golangci-lint run ./pkg/... ./cmd/... are clean. Both directions were also checked against a live Snowflake account, in process through the real ConnectorServer:

issue-credentials alone, sync-secrets off — full lifecycle, and a real sync discovers the token, which is the case the annotation rule exists for:

IssueCredential  -> DISCOVERABLE, expires 2026-09-10
real sync        -> programmatic_access_token count = 1 (4 walks over 3 users)
DeleteResourceV2 -> no error
real sync        -> count = 0

sync-secrets alone, issue-credentials off — the issuer is genuinely gone rather than merely unadvertised:

IssueCredential -> rpc error: code = Unimplemented
                   desc = resource type does not have credential issuer configured

One thing worth knowing, not fixed here

make generate does not regenerate pkg/config/conf.gen.go. There is no //go:generate directive anywhere in pkg/config, so its go generate ./pkg/config is a no-op, and running the generator directly (go run ./pkg/config/gen) writes conf.gen.go to the repo root rather than into pkg/config. The regenerated file is committed separately here; the Makefile is left alone since it is unrelated to this change.

highb and others added 2 commits August 26, 2026 14:50
sync-secrets gated four things at once: the secret and RSA public key syncers,
the programmatic access token syncer, the token child-resource annotation, and
the credential issuer itself. A tenant that wanted a secret inventory had to
grant token minting to get it, and a tenant that wanted issuance had to take a
full secret inventory it may not want.

issue-credentials splits the issuer out. The two flags are independent, with one
deliberate overlap: the programmatic access token type is synced when either is
set. Issuance advertises DISCOVERABLE, so enabling it has to make issued tokens
syncable even with the broader secret sync off, or the credential exists with
nothing holding a handle to revoke it. secretOptions.tokensSynced carries that
rule in one place rather than repeating the disjunction at each site.

| sync-secrets | issue-credentials | secret types synced | issuer |
|---|---|---|---|
| off | off | none | no |
| on | off | secret, rsa_public_key, programmatic_access_token | no |
| off | on | programmatic_access_token | yes |
| on | on | all three | yes |

Nothing regresses: credential issuance is not on main, so no tenant has it today,
and sync-secrets keeps doing exactly what it does now. issue-credentials defaults
to off, which is the right default for a capability that mints credentials.

Co-authored-by: c1-squire-dev[bot] <c1-squire-dev[bot]@users.noreply.github.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Generated by go run ./pkg/config/gen. Note that make generate does not do this:
there is no //go:generate directive in pkg/config, so go generate ./pkg/config is
a no-op, and the generator writes conf.gen.go to the repo root rather than into
pkg/config.

Co-authored-by: c1-squire-dev[bot] <c1-squire-dev[bot]@users.noreply.github.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@linear-code

linear-code Bot commented Aug 26, 2026

Copy link
Copy Markdown

IGA-3962

highb and others added 2 commits August 26, 2026 14:52
Co-authored-by: c1-squire-dev[bot] <c1-squire-dev[bot]@users.noreply.github.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The help block in the README is a hand-maintained snapshot that has drifted from
the real --help output well beyond this flag: it is missing --auth-method,
--health-check, --http-timeout-seconds, --storage-engine, --workers and the
external-resource and otel flags, and several descriptions are stale. Nothing in
CI gates it. Refreshing the whole block is left alone here rather than bundled
into an unrelated change.

Co-authored-by: c1-squire-dev[bot] <c1-squire-dev[bot]@users.noreply.github.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant