Skip to main content

Cloud Governance

The company-wide standard for tracking Azure resources, costs, and access across the three Wasteology-owned subscriptions. Live state is queried on demand; this page holds the durable policy — ownership, intent, and process.

Wasteology cloud governance — the code-to-governance journey: three subscriptions (dev / prod / orbit), live-state tracking via ops azure, the two independent access layers, code-first provisioning, and the automatic change trail

Guiding principle: never hand-maintain what Azure already knows

Resource lists, role assignments, and costs live in Azure Resource Graph and Cost Management. Query them with the ops azure CLI. This document records only what Azure cannot: ownership, intent, and process.

Scope is the three Wasteology-managed subscriptions below. The Pathfinder Dev/Prod subscriptions are deliberately out of scope for this standard.


Subscription Map

The three subscriptions this standard governs, all in tenant 094ceb6c-a94d-47ad-a049-1cb1edca9e45. Each maps to a short alias used by the ops azure CLI (--sub dev|prod|orbit).

AliasSubscriptionIDRole
devWasteology Development669a4356-6871-4f9b-9256-ba98d5a6eb4cAll dev/CI resources: dev DBs, CieTrade ACI execution, source ACRs, BINS dev
prodWasteology Productiona5a6818e-a0c0-4c6a-8b5c-21e91d75caa8Always-on platform apps, prod DBs, non-CieTrade ACI, palantiri, CieTrade SQL source
orbitWasteology-Orbit60e2b27e-fc5d-4b4b-81a9-ae650e8f2adfDedicated Orbit work-order platform (Mars pilot)

Tracking Model

Three layers, each with a distinct home and refresh cadence. The point of separation is that live state goes stale the moment it is written down, so only policy and decisions are version-controlled. The overview infographic at the top of this page shows how the three layers relate.

LayerAnswersHomeRefresh
Live stateWhat exists, who has RBAC, what it costs right nowAzure Resource Graph + Cost Management via ops azureOn demand — never stale
Durable policyWho owns it, why it exists, how to request/provisionThis pageGit-reviewed edits
Change trailWho granted what, whenDB grants → wg_digests.dbaccess_audit_log; RBAC/provisioning decisions → git historyAutomatic

Live state — ops azure

On-demand queries against live Azure, scoped to the three subscriptions above. No data is stored; every run reflects current state. Full command reference: ops azure.

CommandPurpose
ops azure inventory [--sub] [--type]Resource Graph listing of all resources (filter by subscription or type substring)
ops azure costs [--sub] [--by resourcegroup|service]Month-to-date actual cost from Cost Management, grouped and totalled
ops azure access [--sub] [--resource] [--principal]RBAC role assignments at subscription or resource scope, filterable by principal
ops azure identitiesService principals (owned app registrations) + user-assigned managed identities we run
note

ops azure costs requires the costmanagement az extension (az extension add --name costmanagement) — the command prints this hint if it is missing.


Database Servers

The seven database servers within the three governed subscriptions. Data-plane access differs sharply by auth mode — see the note after the table.

ServerEngineSubResource GroupAuth mode
pg-wasteologyPostgreSQL Flexdevwasteology_pg_devAAD + password
billing-modernization-devPostgreSQL Flexdevbins-devpassword only (AAD off)
pathfinder-devAzure SQLdevpathfinder_data_devSQL/AAD
app-wasteology-prodPostgreSQL Flexprodwasteology_pg_prodAAD + password
billing-modernization-prdPostgreSQL Flexprodbins-prodpassword only (AAD off)
wasteologyAzure SQLprodinvoice-automationAAD + SQL (CieTrade source)
wg-pg-orbit-prodPostgreSQL Flexorbitorbit-rg-prodAAD only (password off) — strongest posture
Auth mode matters

AAD-admin servers are governed by roles managed through ops db; password-only servers (BINS) are governed entirely by native Postgres roles that are invisible to Azure RBAC. Auditing "who has access" therefore requires checking both layers.


Access Model

Azure access has two independent layers. A principal can hold one without the other, so both must be checked when auditing "who has access."

Control-plane (Azure RBAC)

Governs who can manage or read the Azure resource itself. Inherited from subscription/RG scope down to the resource. Query with ops azure access.

Standing grants across all three subscriptions:

  • ABS, CGreco, CGreco-a hold User Access Administrator (they can grant any role)
  • ashull holds Owner
  • kgray is User Access Administrator only on the Prod prefect-resources RG

Data-plane (database)

Governs who can actually connect and read/write rows. For AAD-enabled Postgres this is the server's Azure AD administrator(s) plus native Postgres role membership, managed through the DB Access Manager page and the ops db CLI.


Access-Request Runbook

The sanctioned paths to grant access. Prefer the tooling below over hand-editing in the Azure portal so every change is auditable and repeatable.

Grant database access

Use the ops db CLI (or the DB Access Manager page's edit mode, gated by DBACCESS_MUTATION_ALLOWLIST). Both target WASTE_PG_DEV (dev) by default; pass --conn WASTE_PG for prod.

ops db grant-schema <user> --schema <schema> --access read|readwrite   # schema access
ops db add-to-role <user> --role wasteology_admin # role membership
ops db add-to-role <user> --role azure_pg_admin --conn WASTE_PG_DEV # DB admin (dev)
azure_pg_admin is a privilege escalation

azure_pg_admin is Azure's managed-Postgres substitute for superuser — members manage roles, extensions, and all non-system objects. Grant it deliberately and reverse with remove-from-role.

Grant Azure RBAC

RBAC role assignments must be made by a User Access Administrator (ABS, CGreco) or an Owner (ashull).

kgray can grant only within the Prod prefect-resources RG without escalation. For anything else, request the grant from a UAA holder specifying:

  1. Principal — the user or service principal
  2. Role — the specific role definition
  3. Scope — the narrowest that works (resource > RG > subscription)

Provisioning New Resources

New Azure infrastructure is defined as code, not clicked together in the portal. The /infra Bicep path is the sanctioned route for compute; new projects follow the Claude Project Standard.

  • Container Apps and supporting resources deploy via the /infra Bicep templates (infra/) into wdp-palantiri-rg. Always run what-if before a prod deploy.
  • New projects follow the bootstrap: ADO repo → CLAUDE.md → skills → manifest registration.
  • Register every project in manifests/builtin/<project>.toml so digest and standup pick it up.

Service Principals & Managed Identities

The non-human identities that operate Wasteology infrastructure. List them live with ops azure identities; the entries below are the durable ownership notes and cleanup flags.

Managed identities (no secrets — preferred): wg-azure-infra-identity (ADO CI/CD), enevo-etl-identity, enevo-managed-identity, orbit-identity-{dev,prod,sandbox}, orbit-migrator-prod, bins-{dev,prd}-{mi,deployer}, deck-builder-identity, pathfinder-mi.

App-registration service principals (credential-based):

SPPurposeGovernance note
prefect-workpool-spSpins ACI containers, ACR pull, KV secretsActive
CieTrade Pipeline DevCieTrade ETL DB auth; secret fetched at runtime from Key VaultValid to 2028-05; expired 2026-05 credential should be cleaned up
DBTCloudServicePrincipaldbt Cloud → pg-pathfinderActive
orbit-github-actionsOrbit CI/CD deploys (OIDC/federated, no secret)Active
PowerBI-MCP-IntegrationPower BI integration⚠️ holds Contributor across the entire Dev subscription — scope down
ach-remittance-senderACH remittance email flowValid to 2028-05
Cleanup candidates (2026-07-16 audit)

Two stale azure-cli-* / GUID-named SPs hold Contributor on the Prod invoice-automation RG (leftover ad-hoc az logins); pathfinder-ext-tables secrets expired 2024-11 (likely dead). Verify no dependencies, then remove.


Team Rollout & Ownership

How this model reaches the team and stays maintained: it is delivered through the four channels the team already uses, monitored by push rather than pull, and owned with a fixed review cadence.

The proliferation principle mirrors the rest of the platform — the team does not clone the operator hub or install the ops CLI. Governance surfaces where they already work: the published docs site, the wdp-palantiri dashboard, and Claude Code from any repo via a global agent.

Delivery channels

The four team-facing surfaces this reaches, and the phase each lands in. None require the team to run the ops azure CLI directly.

ChannelSurfacePhase
Published docs pageInternal docs site — this Cloud Governance page + azure CLI page, auto-synced1
Onboarding guideShareOnboardingGuide link opened in Claude Code — "how to run & manage" playbook1
Global agentazure-governance-auditor in wg-agent-infra — any teammate audits/grants/reports from any repo2
Dashboard pagewdp-palantiri "Azure Governance" page (live inventory/cost/access)2

Monitoring

Monitoring must arrive uninvited, so it is push-based, not a dashboard someone must remember to open. Two mechanisms, both phase 2.

  • Digest / Morning Brief — a weekly Azure cost + access section in ops digest / standup, so totals and deltas land in the brief everyone reads.
  • Drift detection — a scheduled check that flags the risky changes: new service principals, credentials expiring within 30 days, and new User Access Administrator / Owner grants.
  • Optional backstop — native Azure Cost Management budgets with email alerts per subscription catch spend spikes with zero code; not yet enabled.

Ownership & cadence

Governance decays without an owner and a schedule. The owner runs the cadence below and is the approver for the access-request runbook above.

ItemCadenceOwner
Cost review (via digest)WeeklyPlatform owner (kgray)
Access review (RBAC + DB roles)MonthlyPlatform owner
Service-principal & credential cleanupQuarterlyPlatform owner

Rollout phases

Sequenced so visible value ships first and the heavier build follows.

  • Phase 1 (fast wins): publish the docs page; ship the onboarding-guide link. Governance becomes readable and discoverable company-wide.
  • Phase 2 (self-service + monitoring): build the azure-governance-auditor global agent; add the digest cost/access section and drift detection; build the wdp-palantiri dashboard page.