Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 21 additions & 3 deletions internal/cloud/cloudstore/identity.go
Original file line number Diff line number Diff line change
Expand Up @@ -906,9 +906,22 @@ func guardLastActiveAdminTx(ctx context.Context, tx *sql.Tx, principalID string,
return nil
}

// auditKeyValueExempt reports whether a (key, value) pair should bypass the
// sensitive-key heuristic based on its value. issued_token is a boolean flag
// written by the bootstrap completion audit (see cloudBootstrapCompletionMetadata);
// it is exempt ONLY when the value is actually a bool, so the exemption cannot
// be used to smuggle a secret string under a trusted key name.
func auditKeyValueExempt(key string, value any) bool {
if strings.EqualFold(strings.TrimSpace(key), "issued_token") {
_, ok := value.(bool)
return ok
}
return false
}

func rejectSensitiveAuthAuditMetadata(metadata map[string]any) error {
for key, value := range metadata {
if sensitiveAuthAuditKey(key) {
if !auditKeyValueExempt(key, value) && sensitiveAuthAuditKey(key) {
return fmt.Errorf("%w: %s", ErrSensitiveAuditMetadata, key)
}
if err := rejectSensitiveAuthAuditValue(value); err != nil {
Expand Down Expand Up @@ -936,10 +949,11 @@ func rejectSensitiveAuthAuditValue(value any) error {
}
for _, key := range reflected.MapKeys() {
keyText := key.String()
if sensitiveAuthAuditKey(keyText) {
entryValue := reflected.MapIndex(key).Interface()
if !auditKeyValueExempt(keyText, entryValue) && sensitiveAuthAuditKey(keyText) {
return fmt.Errorf("%w: %s", ErrSensitiveAuditMetadata, keyText)
}
if err := rejectSensitiveAuthAuditValue(reflected.MapIndex(key).Interface()); err != nil {
if err := rejectSensitiveAuthAuditValue(entryValue); err != nil {
return err
}
}
Expand All @@ -955,6 +969,10 @@ func rejectSensitiveAuthAuditValue(value any) error {

func sensitiveAuthAuditKey(key string) bool {
key = strings.ToLower(strings.TrimSpace(key))
// token_prefix is the short, non-secret token prefix; it matches the
// fragment heuristic below but never carries secret material. issued_token
// is handled by auditKeyValueExempt instead, because it is only safe when
// its value is the boolean flag the bootstrap completion audit records.
if key == "token_prefix" {
return false
}
Expand Down
25 changes: 25 additions & 0 deletions internal/cloud/cloudstore/identity_storage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,31 @@ func TestCloudstoreIdentityPureHelpers(t *testing.T) {
if err := rejectSensitiveAuthAuditMetadata(map[string]any{"events": []map[string]any{{"raw_token": "secret"}}}); !errors.Is(err, ErrSensitiveAuditMetadata) {
t.Fatalf("typed nested slice sensitive audit metadata must be rejected, got %v", err)
}
// Regression: the bootstrap completion audit metadata (created by
// cloudBootstrapCompletionMetadata) carries the boolean flag "issued_token".
// It is not a secret and must be accepted, otherwise
// `engram cloud bootstrap admin --issue-token` fails atomically and no admin
// token is ever minted.
if err := rejectSensitiveAuthAuditMetadata(map[string]any{"issued_token": true, "username": "admin", "created_admin": true}); err != nil {
t.Fatalf("bootstrap completion metadata must be accepted, got %v", err)
}
// issued_token is false for grant-only bootstraps (no --issue-token); both
// boolean values must be accepted.
if err := rejectSensitiveAuthAuditMetadata(map[string]any{"issued_token": false}); err != nil {
t.Fatalf("false issued_token must be accepted, got %v", err)
}
// issued_token is exempt ONLY as a boolean flag. A non-boolean value (e.g. a
// string that could carry secret material) must NOT bypass the filter, at
// the top level or nested.
if err := rejectSensitiveAuthAuditMetadata(map[string]any{"issued_token": "egc_live_would_be_leaked"}); !errors.Is(err, ErrSensitiveAuditMetadata) {
t.Fatalf("non-boolean issued_token must be rejected, got %v", err)
}
if err := rejectSensitiveAuthAuditMetadata(map[string]any{"outer": map[string]any{"issued_token": "egc_live_would_be_leaked"}}); !errors.Is(err, ErrSensitiveAuditMetadata) {
t.Fatalf("nested non-boolean issued_token must be rejected, got %v", err)
}
if err := rejectSensitiveAuthAuditMetadata(map[string]any{"outer": map[string]any{"issued_token": true}}); err != nil {
t.Fatalf("nested boolean issued_token must be accepted, got %v", err)
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}

func tableExists(t *testing.T, db *sql.DB, table string) bool {
Expand Down