Skip to content

Warn users that keyless evidence signing publishes their identity to a public transparency log #1257

Description

@njhensley

[Feature]: Warn users (docs + interactive CLI gate) that keyless evidence signing publishes their identity to a public transparency log

Suggested labels: feature, documentation, area/cli, needs-triage
Suggested component: CLI (aicr)

Feature Summary

The evidence-signing CLI paths (aicr validate --emit-attestation --push, aicr evidence publish --push, and aicr bundle --attest) can fall through to an interactive browser / device-code OIDC login that mints a short-lived Sigstore (Fulcio) certificate from the user's identity. With public-good Sigstore that identity — typically the signer's email address plus the OIDC issuer — is embedded in the signing certificate and written to the public, immutable Rekor transparency log. We never tell the user this is about to happen.

This issue proposes (1) documenting the privacy/PII implication clearly, and (2) adding an interactive CLI gate — a warning banner plus a confirmation pause before the browser flow opens — with a flag to bypass it for automation.

Problem / Use Case

When a user runs an evidence command without a pre-supplied token, the OIDC precedence chain ends at the interactive path:

--identity-token / COSIGN_IDENTITY_TOKEN  →  GitHub Actions ambient OIDC  →  --oidc-device-flow  →  interactive browser flow

(see pkg/evidence/attestation/emit.go:312-322 and docs/user/cli-reference.md "OIDC Token Sources")

On the interactive path:

  • FetchInteractiveOIDCToken opens a browser to a Sigstore-supported IdP (GitHub / Google / Microsoft) — pkg/bundler/attestation/oidc.go:106-117.
  • The returned token is exchanged at Fulcio for a short-lived cert whose SAN embeds the authenticated identity (email) and issuerpkg/bundler/attestation/signing.go (SignStatementSignedAttestation{Identity, Issuer, ...}).
  • The signature + certificate are recorded in Rekor, the Sigstore transparency log. With the public-good default (rekor.sigstore.dev) this log is public and append-only — entries cannot be deleted. The same identity-bearing Sigstore bundle is also attached to the pushed OCI artifact as a referrer (emit.go:287-303).

The net effect: a user who just wanted to sign an evidence bundle can permanently publish their email address to a globally searchable public log, and today the only hint is a couple of slog.Info lines ("opening browser for Sigstore OIDC authentication...", emit.go:319-321). There is no warning and no confirmation before the browser opens — unlike, e.g., confirmOverwrite in pkg/cli/skill_generator.go:335, which already pauses on a TTY for a far less consequential action.

This is a real privacy/PII gap: the consequence is irreversible (public, immutable log), the data is personal (email), and consent is implicit.

Nuance worth capturing: the exposure severity depends on the endpoint. Public-good Sigstore (fulcio.sigstore.dev / rekor.sigstore.dev) makes the identity world-readable forever. A privately hosted Fulcio/Rekor (--fulcio-url / --rekor-url, docs/user/cli-reference.md:1093-1094) keeps identity inside org infrastructure. The warning should reflect which endpoints are actually in use.

Proposed Solution

1. Documentation

  • Add a "Privacy / identity in keyless signatures" subsection under the Bundle Attestation → OIDC Token Sources area of docs/user/cli-reference.md, and cross-link it from the aicr validate --emit-attestation, aicr evidence publish, and aicr bundle --attest sections. It should state plainly:
    • Keyless signing embeds the signer's OIDC identity (email + issuer) in the certificate.
    • With public-good Sigstore that identity is written to the public, immutable Rekor transparency log and is permanently searchable.
    • It is also attached to the pushed OCI artifact (visible to anyone who can pull it).
    • Ways to control exposure: use a service/CI ambient identity instead of a personal one; supply a pre-fetched --identity-token minted from a non-personal identity; or point --fulcio-url/--rekor-url at private Sigstore infrastructure.
  • Mention the privacy implication in the ADR-007 docs (docs/design/007-recipe-evidence/02-identity-and-policy.md) so the design rationale is recorded.

2. CLI interactive gate + warning banner

Before the interactive paths only (browser callback and device-code — not the non-interactive --identity-token / ambient paths), emit a clear warning banner describing what is about to be published, then:

  • When stdin is a TTY: pause for an explicit y/N confirmation (reuse the established term.IsTerminal + stdin-prompt pattern from pkg/cli/skill_generator.go:335). Default to "no".
  • When stdin is not a TTY (CI, pipes): do not block — print the warning banner and proceed (fail-safe; blocking would break scripted/CI usage). A slog.Warn-level banner is appropriate here.
  • Add a bypass flag for scripted-but-interactive shells, e.g. --yes / --assume-yes (with AICR_ASSUME_YES env), which suppresses the prompt while still printing the banner.
  • Make the banner endpoint-aware: name the Fulcio/Rekor URLs in effect and call out when they are the public-good defaults vs. a private instance.

The gate should live in the CLI layer (pkg/cli/validate_evidence.go, pkg/cli/evidence_publish.go, pkg/cli/bundle.go) so business-logic packages stay non-interactive, consistent with the repo's CLI/business-logic separation.

Success Criteria

  • Running an evidence command that would open a browser/device-code flow prints a banner that names: the data published (OIDC identity / email), the destination (public Rekor + OCI artifact), and that it is permanent/irreversible on public Sigstore.
  • On a TTY, the flow pauses for explicit confirmation and aborts cleanly (no browser opened, non-zero exit) on decline.
  • Non-interactive (CI / piped stdin) runs are not blocked — banner is emitted, flow continues.
  • A documented bypass (--yes / AICR_ASSUME_YES) skips the prompt for interactive automation.
  • Pre-fetched --identity-token and ambient GitHub Actions OIDC paths are unaffected (no prompt — they are already non-interactive and don't surprise the user with a browser).
  • docs/user/cli-reference.md documents the privacy implication and the new flag/behavior in the same PR (per the docs-with-behavior-change rule).
  • Unit tests cover: TTY-confirm accept/decline, non-TTY pass-through, --yes bypass, and that non-interactive token sources never trigger the gate.

Alternatives Considered

  • Docs-only. Insufficient — the consequence is irreversible and consent is currently implicit; a warning at the point of action is warranted.
  • Hard block in non-interactive mode (require --yes in CI). Rejected — would break existing CI/scripted signing with no safety benefit, since CI already uses ambient/non-personal identities.
  • Default to device-code or private Sigstore. Out of scope here; this issue is about informed consent for the existing default, not changing the default trust root.

Affected Code / Docs (pointers)

  • pkg/cli/validate_evidence.go, pkg/cli/evidence_publish.go, pkg/cli/bundle.go — add the gate/banner + --yes flag.
  • pkg/evidence/attestation/emit.go:312-322 — current slog.Info-only signaling.
  • pkg/bundler/attestation/oidc.go:106-136 — interactive browser / device-code flows.
  • pkg/cli/skill_generator.go:335 — existing confirmOverwrite TTY-prompt pattern to reuse.
  • docs/user/cli-reference.md — Bundle Attestation / OIDC Token Sources, evidence publish, validate sections.
  • docs/design/007-recipe-evidence/02-identity-and-policy.md — design rationale.

Metadata

Metadata

Assignees

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions