flightcheck: add INFRA-011 connector secret storage check (verify sec…#186
flightcheck: add INFRA-011 connector secret storage check (verify sec…#186daeunJe0ng wants to merge 10 commits into
Conversation
…rets are Key Vault-backed, not inline plaintext) Detect-first gate over Dataverse env vars + connection references: - Secret-type (Key Vault-backed) env var -> PASSED + MANUAL vault hardening - Raw secret in a Text env var -> FAILED - Secret inside a connection (Workday legacy ISU, ServiceNow) -> MANUAL - No secret-bearing auth -> informational PASSED Documented Dataverse tier only; no Azure Key Vault API call. Plaintext scan covers secret/password/token/apikey/credential naming. Adds validation-matrix row and 12 tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…lse positives, fix import) - Import auth.query_all at module top level instead of runtime sys.path manipulation, matching the _dlp_utils convention (cli.py already puts scripts/ on the path at startup). - Split secret-name detection into HIGH (secret/password/pwd/clientsecret -> FAILED) and BROAD (token/apikey/credential -> WARNING) tiers so ambiguous names like TokenEndpointUrl no longer block readiness. - Document why an unknown env var type is treated as Text (a real KV-backed secret carries a Key Vault reference, filtered out before FAIL). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Reviewer Context PR #186 - INFRA-011 Connector Secret Storage Safety - ADO task What this PR adds How it decides (detect-first gate) Manual end-to-end validation done against a live environment (test-dawn) Changes made during review Known coverage gaps worth a reviewer decision (not blockers) JSON-type env vars are not scanned by value. Detection is name-based on Text vars only. AC2 interpretation. The task AC2 says scan flow definitions for inline plaintext secrets via pattern match. Suggested reviewer focus |
OverallSolid, well-grounded PR. The three-outcome detect-first design is sound, statuses map correctly to readiness buckets (only high-confidence FAILED blocks; WARNING/MANUAL/PASSED/SKIPPED don't), the Workday ISU suffixes ( Gaps worth addressing1. 2. Secret-type env var reported PASSED even when unbound. In the value loop, a 3. 4. No API-tier / Nits
CC: @daeunJe0ng |
…1 (close default-only secret blind spot) The check only scanned environmentvariablevalues rows, so a secret pasted into a definition's defaultvalue with no override row went unscanned and produced a false PASS. Solution-imported vars commonly ship default-only, so this was a real inline-secret path. Now iterate definitions and evaluate the effective value (override else defaultvalue); a Secret-type var is reported as safely stored only when it holds a value. Adds default_value to the env_var_def mock and 3 effective-value tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 09474229-6aac-4d8a-906e-b94d2a4c2f6a
Summary
Adds a new FlightCheck pre-deployment check, INFRA-011 (connector secret storage safety), to the ESS Maker Kit. It verifies connector credentials are stored safely (in a Key Vault-backed Power Platform environment variable) rather than pasted inline as plaintext, and surfaces connection-stored secrets the platform never exposes for manual verification.
The check is a detect-first gate over Dataverse environment variables and connection references, with these outcomes:
0786a/d6081, or any ServiceNow connection) -> MANUAL.Design rationale
environmentvariabledefinitions/environmentvariablevalues/connectionreferencesvia the existingauth.query_all. No new external API is called. Read-only and idempotent (GETs only).Effective-value evaluation
The classification loop iterates environment variable definitions and evaluates the effective value: the current-value override when present and non-empty, otherwise the definition's
defaultvalue. This closes the blind spot where a secret pasted into a definition's default value (with no override record, common for solution-imported vars) would go unscanned. ASecret-type definition is only reported as safely stored when it actually holds a value; an unbound one is not asserted safe.Testing
tests/flightcheck/checks/test_infrastructure_secret_storage.py(18 tests) covering all outcomes, multi-resource bucketing, the KV-reference-in-Text-var non-flag case, thetokenkeyword path, both SKIPPED (missing token / missing env URL) paths, plus the effective-value cases: plaintext secret indefaultvalue-only -> FAILED, Key Vault reference indefaultvalue-only -> not flagged, and unbound Secret-type var -> not reported as stored. Tests assert onresultANDremediationphrases per the repo test rules.python -m pytest tests/flightcheck/checks/test_infrastructure_secret_storage.py -qManual end-to-end validation (live environment)
Exercised against a live Power Platform environment via a probe that calls the check with a cached Dataverse token.
Validated:
--scope full.apikey/tokenText var: WARNING / Medium, remediation shows--scope full.Pending (blocked on live Azure Key Vault access, in progress):
--scope infrastructure(no Dataverse auth) and missing environment URL.Risks / assumptions / known scope limits
FAST-FOLLOWcomment ininfrastructure.py).Files
solutions/ess-maker-skills/scripts/flightcheck/checks/infrastructure.py- the check + helpers, registered in_INFRA_CHECKS.solutions/ess-maker-skills/src/reference/ess-docs/flightcheck/validation-matrix.md- INFRA-011 row.tests/flightcheck/checks/test_infrastructure_secret_storage.py- tests.tests/mocks/dataverse.py-env_var_defmock gainsdefault_value.