CtrlK
BlogDocsLog inGet started
Tessl Logo

azure-governance-discovery

**ANALYSIS SKILL** — Azure Policy discovery: effective assignments (incl. MG-inherited), definitions/exemptions, effect classification, emits governance-constraints JSON. WHEN: 'Azure policy discovery', 'effective policy assignments', 'governance constraints', '04g-Governance Phase 1', 'refresh governance JSON'. DO NOT USE FOR: artifact writing, architecture mapping.

71

Quality

86%

Does it follow best practices?

Impact

No eval scenarios have been run

SecuritybySnyk

Passed

No known issues

SKILL.md
Quality
Evals
Security

Azure Governance Discovery Skill

Replaces the legacy governance-discovery-subagent with a deterministic script. The skill exposes scripts/discover.py — a single batched REST traversal that emits the schema-compliant 04-governance-constraints.json envelope. The parent agent (04g-Governance) invokes it via run_in_terminal, reads a compact one-line JSON status from stdout, and proceeds to artifact writing without ever pulling raw Azure REST responses into LLM context.

When to Use

  • Step 3.5 governance discovery for a project
  • Refreshing the governance snapshot after policy changes
  • Regenerating inputs for Step 4 (IaC Plan) and Step 5 (IaC Code)

When NOT to Use

  • Writing 04-governance-constraints.md — that stays in the parent agent
  • Cross-referencing architecture resources — parent-side LLM work
  • Challenger review orchestration — parent-side LLM work
  • Any workflow that is not 04g-Governance

Rules

  • Stay deterministic — the discovery script is a single batched REST traversal; no LLM calls, no retries that hide errors, no inferred policy effects
  • Never pull raw Azure REST responses into LLM context — stdout is exactly one machine-readable JSON status line; the parent agent reads only this line
  • Schema compliance is mandatory — envelope MUST conform to tools/schemas/governance-constraints.schema.json (schema_version: governance-constraints-v1)
  • Property paths are always strings — use "" for unresolvable paths, never null
  • Filter Defender auto-assignments by default — they create policy noise that masks real governance constraints; opt-in via --include-defender-auto
  • Exit codes are contract0 = COMPLETE, 1 = PARTIAL, 2 = FAILED, 3 = invalid args; the parent agent routes solely on these codes
  • No artifact writing — the script emits JSON + a .preview.md; the agent owns the final 04-governance-constraints.md content and traffic-light rendering
  • Re-run with --refresh when policy state has changed; otherwise honor the existing JSON

Steps

python .github/skills/azure-governance-discovery/scripts/discover.py \
    --project my-project \
    --out agent-output/my-project/04-governance-constraints.json

Flags:

FlagMeaning
--project <name>Required. Used only for cache key and provenance.
--out <path>Required. Full envelope written here (overwrites).
--subscription <id|default>Optional. default uses az account show.
--refreshForce re-discovery even if <out> already exists.
--include-defender-autoInclude Defender-for-Cloud auto-assignments (excluded by default).

Exit codes:

CodeMeaning
0COMPLETE — discovery succeeded
1PARTIAL — partial data written; parent should surface to user
2FAILED — auth/network/permission error
3Invalid arguments

Stdout — always exactly one machine-readable JSON line first, optional human-readable preview after:

{
  "status": "COMPLETE",
  "cache_hit": false,
  "assignment_total": 247,
  "blockers": 18,
  "auto_remediate": 12,
  "exempted": 3,
  "out_path": "agent-output/my-project/04-governance-constraints.json"
}

Output Contract

The script writes a JSON envelope conforming to tools/schemas/governance-constraints.schema.json (schema_version: governance-constraints-v1). Each finding carries both bicepPropertyPath and azurePropertyPath (always strings — empty "" when unresolvable, never null), plus category, exemption, and classification ("blocker" | "auto-remediate" | "informational"; exempted Deny/Modify blockers downgrade to "informational"). Top-level envelope also includes policies (alias of findings), tags_required, allowed_locations, and discovery_metadata (L0 attestation envelope — MANDATORY).

For the full per-finding schema and additive fields, read references/schema.md.

For the L0 envelope spec (shape, completeness-signature algorithm, end-of-discovery self-check, refresh handoff, consumer protocol, backward-compatibility rules), read references/l0-envelope.md.

For the effect classification table and Defender-filter rationale, read references/effect-classification.md.

Preview Markdown

The script also writes a sibling .preview.md file (e.g., 04-governance-constraints.preview.md) with the H2 structure matching the azure-artifacts template. The agent copies this to 04-governance-constraints.md and annotates placeholder sections only.

Reference Index

References are split into two tiers so the agent loads only what it needs:

Load-always (the minimum to drive the core workflow):

  • references/terminal-commands.md — pre-built batched commands (Cmd 1–8) for the entire phase.

Load-on-demand (read only when the relevant decision point is reached):

  • references/effect-classification.md — effect-to-classification mapping, exemption downgrade, Defender filter rationale
  • references/schema.md — output JSON envelope, findings[] structure, additive fields
  • references/l0-envelope.md — canonical L0 envelope spec (shape, signature algorithm, self-check, refresh handoff, consumer protocol)
  • references/inline-resolution-gate.md — Phase 2.7 protocol + signature/TTL short-circuit
  • references/baseline-check.md — Phase 0.45 cached-baseline procedure
  • references/policy-override-pattern.md — structured override object shape
  • references/reconciliation-disposition.md — Phase 2.5 disposition rules
  • references/resume-checks.md — Phase 0.4 short-circuit conditions (signature, TTL, confirmations)
  • references/discover-output.mddiscover.py stdout shape, exit codes, anti-patterns, discovery-signature persistence

Design Notes

  • Three batched REST list calls only: policyAssignments?$filter=atScope(), policyDefinitions (subscription + tenant built-ins), policySetDefinitions. One more list for policyExemptions?$filter=atScope().
  • In-process classification and property-path extraction; no per-assignment GETs.
  • Caches on the presence of <out> unless --refresh passed.
  • Defender auto-assignments (properties.metadata.assignedBy == "Security Center") are filtered by default — matches EPAC's default and trims typical tenant row counts by 30-60%. Every filtered assignment is logged to stderr.

Testing

pytest .github/skills/azure-governance-discovery/scripts/test_discover.py
# or
npm run test:governance-discovery

Fixtures live in scripts/fixtures/ and simulate az rest responses via subprocess.check_output monkeypatching — no Azure account required for tests.

Repository
jonathan-vella/azure-agentic-infraops
Last updated
Created

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.