Files
KRATOS a6d6939bc5 audit: fix isolated remaining findings (redaction, secrets, rune-safety, credential status) (#174)
* audit: fix redaction sibling-DAG false cycle, hoist URL regex, widen OpenAI key pattern

- redaction: seen-set now tracks only the current DFS path (delete pointer
  after recursing) so a shared reference reached via a sibling branch is no
  longer reported as CircularReference; true cycles still detected. (audit
  redaction.go:222)
- redaction: redactURLPasswords compiles its regexp once at package scope
  instead of per call. (audit redaction.go:362)
- secrets: openai_key body allows - and _ so sk-proj-/sk-svcacct- keys match,
  not just legacy sk-<alnum>. (audit scanner.go:35)

* audit: rune-safe cron run-error truncation and commit-subject length

- cronTruncate now cuts on a UTF-8 rune boundary (via cutRuneBoundary) so a
  persisted cron run-error excerpt can't end in a split rune. (audit cron_run.go:179)
- zerogit ValidateMessage counts runes, not bytes, so a valid non-ASCII commit
  subject under 72 chars is no longer rejected. (audit zerogit.go:207)

* audit: report auth-header-only profiles as having a credential

ProviderSnapshot.APIKeySet was true only for a non-empty APIKey, so a profile
authenticated solely via AuthHeaderValue rendered as 'not set' in the command
center. Treat either credential as set. (audit contracts.go:166)

* audit: address review on #174 (credential-presence coverage + consistency)

- Add ProviderSnapshotFromProfile test covering APIKeySet for api-key-only,
  auth-header-only, both, and neither (the AuthHeaderValue path CodeRabbit
  flagged as untested).
- doctor.go: report the provider 'apiKey' diagnostic as set when EITHER APIKey
  or AuthHeaderValue is present, matching ProviderSnapshot.APIKeySet — closing
  the same auth-header-only gap at the other credential-check site.
- scanner_test: also assert the [REDACTED:openai_key] placeholder is present
  (matches the pattern used by the existing redaction test).

* audit: trim credentials + surface doctor credential presence (#174 review)

- ProviderSnapshot test: add whitespace-only api-key / auth-header cases so the
  TrimSpace behavior stays covered.
- doctor.go: trim both APIKey and AuthHeaderValue before the presence check
  (matches ProviderSnapshot.APIKeySet) AND move the indicator off the sensitive
  'apiKey' detail key — check() runs RedactValue, so 'apiKey' was always scrubbed
  to [REDACTED], leaving the set/not-set indicator invisible. Now reported under
  'credentialConfigured' so it actually surfaces; added a doctor table test.

No consumer read the old detail key.

* audit: honor AuthHeaderValue in model discovery + base-URL redaction (#174 review)

Two credential-presence consistency gaps flagged on #174:

- providermodeldiscovery: the /models probe gated on (and sent Authorization
  from) profile.APIKey only, so an auth-header-only profile was skipped/sent
  unauthenticated. Gate via discoveryHasCredential (APIKey OR AuthHeaderValue)
  and build the request with providerio.ApplyAuthHeaders, matching how the live
  providers authenticate (honors AuthHeaderValue, AuthHeader, AuthScheme,
  CustomHeaders). APIKey-only behavior is unchanged.
- zerocommands.redactProviderBaseURL now also redacts AuthHeaderValue if it
  leaks into the base URL (variadic secrets, empties dropped).

Adds regression tests for auth-header-only discovery, discoveryHasCredential,
and auth-header redaction in the base URL.

* audit: doctor credential-presence test parity with contracts_test (#174 review)

Add the 'both' and 'whitespace auth header only' cases so
TestProviderConfigCheckCredentialPresence matches the six cases in
contracts_test.go's TestProviderSnapshotAPIKeySetCountsAuthHeaderValue.
2026-06-12 12:48:24 +05:30
..