Skip to content

Secrets hardcoded in policy XML are not redacted on extract #198

Description

@EMaher

Summary

apiops extract is expected to mark secrets as *** REDACTED *** in extracted artifacts, but secrets hardcoded inline in policy XML are exported in cleartext. This is a security issue — secrets can be committed to source control.

Severity

Security / data exposure — inline policy secrets land in Git in plaintext.

Command that triggered the bug

apiops extract

Expected behavior

Secrets embedded in any policy.xml (service, product, API, operation, resolver level) are redacted to *** REDACTED ***, consistent with how secret named values are handled.

Actual behavior

Policy XML is written verbatim. Redaction only applies to NamedValue resources with properties.secret === true; the policy path has no redaction step.

Root cause (confirmed)

  • Redaction is implemented only for NamedValue (src/services/secret-redactor.ts:31, requires properties.secret === true at :41).
  • Policy XML is written verbatim (only HTML-decoded): src/clients/artifact-store.ts:44-70 (writeContent(..., ''policy'')).
  • Extract call sites with no redaction:
    • ServicePolicy — src/services/extract-service.ts:404
    • ProductPolicy — src/services/product-extractor.ts:218
    • ApiPolicy — src/services/api-extractor.ts:287, :366
    • ApiOperationPolicysrc/services/api-extractor.ts:423
    • GraphQLResolverPolicy — src/services/api-extractor.ts:534

Proposed solution (agreed: redact-and-warn)

  1. Detect literal secrets in every policy.xml via a structured scan of known secret-bearing locations: set-header (Authorization, Ocp-Apim-Subscription-Key, x-functions-key, api-key), set-query-parameter (code, sig, subscription-key), authentication-basic password, authentication-certificate inline body, validate-jwt signing/decryption keys, connection-string fragments (AccountKey=, SharedAccessKey=).
  2. Redact each detected literal to *** REDACTED *** (reuse REDACTION_MARKER).
  3. Warn per finding, stating: a secret was found and redacted (naming policy + location); publish will fail due to the redacted secret; and the policy should be updated to use a named value — linking to https://learn.microsoft.com/en-us/azure/api-management/api-management-howto-properties
  4. Fail-safe: a still-redacted policy fails publish loudly rather than leaking or pushing a broken value.

Do NOT redact (non-secret allow-list)

{{namedValue}} references (pointers, not literals), App Insights instrumentation keys / connection strings, AAD tenant/client IDs, public URLs / resource / audience.

Metadata

Metadata

Assignees

Labels

squadSquad triage inbox — Lead will assign to a membertype:bugSomething broken

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions