Skip to content

feat(apim): APIM Policy Management — list APIs, assign templates, app…#32

Open
seiggy wants to merge 14 commits into
Azure-Samples:mainfrom
seiggy:feature/apim-policy-management
Open

feat(apim): APIM Policy Management — list APIs, assign templates, app…#32
seiggy wants to merge 14 commits into
Azure-Samples:mainfrom
seiggy:feature/apim-policy-management

Conversation

@seiggy
Copy link
Copy Markdown
Collaborator

@seiggy seiggy commented May 21, 2026

…ly via SDK

Adds the policy engine's ability to manage APIM policies through a UI instead of hand-edited XML files. Implements McNulty's architecture (Tier B: template apply) end-to-end across infra, backend, frontend, and tests.

M1 — Read-only catalog

  • GET /api/apim/apis, /apis/{id}/operations, /apis/{id}/policy
  • GET /api/apim/apis/{id}/operations/{opId}/policy

M2 — Template library

  • 5 templates under policies/templates/ (entra-jwt-ai, entra-jwt-ai-dlp, subscription-key-ai, subscription-key-ai-dlp, entra-jwt-rest)
  • {{placeholder}} substitution + template.json manifests
  • GET /api/apim/templates

M3 — Apply flow

  • POST /api/apim/apis/{id}/policy (and operation-scoped variant) — async 202
  • DELETE /api/apim/apis/{id}/policy (and operation-scoped variant)
  • Cosmos policy-assignment doc store (existing configuration container)
  • SHA256 hash of generated XML; status transitions pending→applying→synced|failed
  • Azure.ResourceManager.ApiManagement SDK via DefaultAzureCredential

M4 — UI (src/aipolicyengine-ui)

  • New /apis page with tree view (APIs/operations), details panel, assign-template modal with dynamic parameter form, 2s status polling, clear-confirm flow, XML viewer

Infra (Terraform)

  • Custom least-privilege APIM role with only apis/operations read + policies read/write/delete (NOT Service Contributor)
  • Role assignment to Container App managed identity
  • APIM_RESOURCE_ID plumbed to Container App env via deterministic root local (avoids compute<->gateway module cycle)

Tests

  • 76 new tests (TemplateRendering, TemplateLibrary, PolicyAssignmentRepository, ApplyOrchestrator, ApimManagementEndpoints) — 295 passed / 0 failed / 4 skipped
  • Caught and fixed a strict-XML-parse bug in TemplateLibraryService that was rejecting valid APIM policy-expression templates

Non-AI API usage limits (separate feature) is paused per Zack's call; the draft XML lives at .squad/files/non-ai-paused/ until M2 templates are validated.

…ly via SDK

Adds the policy engine's ability to manage APIM policies through a UI instead
of hand-edited XML files. Implements McNulty's architecture (Tier B: template
apply) end-to-end across infra, backend, frontend, and tests.

M1 — Read-only catalog
  - GET /api/apim/apis, /apis/{id}/operations, /apis/{id}/policy
  - GET /api/apim/apis/{id}/operations/{opId}/policy

M2 — Template library
  - 5 templates under policies/templates/ (entra-jwt-ai, entra-jwt-ai-dlp,
    subscription-key-ai, subscription-key-ai-dlp, entra-jwt-rest)
  - {{placeholder}} substitution + template.json manifests
  - GET /api/apim/templates

M3 — Apply flow
  - POST /api/apim/apis/{id}/policy (and operation-scoped variant) — async 202
  - DELETE /api/apim/apis/{id}/policy (and operation-scoped variant)
  - Cosmos policy-assignment doc store (existing configuration container)
  - SHA256 hash of generated XML; status transitions pending→applying→synced|failed
  - Azure.ResourceManager.ApiManagement SDK via DefaultAzureCredential

M4 — UI (src/aipolicyengine-ui)
  - New /apis page with tree view (APIs/operations), details panel,
    assign-template modal with dynamic parameter form, 2s status polling,
    clear-confirm flow, XML viewer

Infra (Terraform)
  - Custom least-privilege APIM role with only apis/operations read + policies
    read/write/delete (NOT Service Contributor)
  - Role assignment to Container App managed identity
  - APIM_RESOURCE_ID plumbed to Container App env via deterministic root local
    (avoids compute<->gateway module cycle)

Tests
  - 76 new tests (TemplateRendering, TemplateLibrary, PolicyAssignmentRepository,
    ApplyOrchestrator, ApimManagementEndpoints) — 295 passed / 0 failed / 4 skipped
  - Caught and fixed a strict-XML-parse bug in TemplateLibraryService that was
    rejecting valid APIM policy-expression templates

Non-AI API usage limits (separate feature) is paused per Zack's call; the
draft XML lives at .squad/files/non-ai-paused/ until M2 templates are validated.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@seiggy seiggy requested a review from a team May 21, 2026 17:22
seiggy and others added 11 commits May 21, 2026 13:42
…e nested config

The Container App env var was named APIM_RESOURCE_ID (single underscore),
but ASP.NET Core's EnvironmentVariablesConfigurationProvider only maps
nested config keys (like Apim:ResourceId) from env vars with double
underscores (Apim__ResourceId). At runtime the binding silently failed,
leaving Apim:ResourceId empty and throwing InvalidOperationException
from ApimCatalogService when the first request hit /api/apim/apis.

Rename the Terraform env var to Apim__ResourceId so it binds correctly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Orchestration log: 2026-05-21T17-43-57Z-freamon.md (APIM_RESOURCE_ID → Apim__ResourceId hotfix)
- Session log: 2026-05-21T17-43-57Z-apim-config-binding-fix.md
- Merge decision into Active Decisions: ASP.NET Core nested config convention (double-underscore env vars)
- Delete inbox file: freamon-apim-config-binding-fix.md
- Cross-agent context: append to sydnor/history.md and kima/history.md

All 295 tests pass. Audit complete: no other single-underscore ASP.NET Core nested-config mismatches.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Root cause: the initial APIM bootstrap callback depended on operationsByApi while also resetting that state, which changed the callback identity and retriggered the mount effect.

Fix: keep the latest operations map in a ref so loadInitialData can reconcile the current selection without depending on the mutable operationsByApi object.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Orchestration log: 2026-05-21T18-35-00Z-kima.md documents the infinite render loop fix
- Session log: 2026-05-21T18-35-00Z-apis-render-loop-fix.md brief summary
- Merged decision inbox: kima-apis-render-loop.md into decisions.md as 2026-05-21T18:35:00Z entry
- Cross-agent update: appended render-loop skill note to bunk/history.md with test coverage suggestion
- Deleted inbox file after merge

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- ApiTree: Add min-w-0 flex-1 truncate to API name, flex-shrink-0 on badge
- ApiTree: Remove redundant serviceUrl display (path is sufficient)
- ApiTree: Simplify operation rows - show method badge + urlTemplate only (removes duplicate verb text)
- AssignTemplateForm: Add min-w-0 + truncate to param label, flex-shrink-0 on badges
- AssignTemplateForm: Change param grid to sm:grid-cols-2 for better modal fit
- Dialog: Add overflow-x-hidden to prevent horizontal scrollbar

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Orchestration log: Kima's /apis layout fixes (ApiTree, AssignTemplateForm, dialog)
- Session log: Brief summary of UI polish completion
- Cross-agent: Append tailwind-flex-truncate-pattern SKILL note to Bunk's history
- Commit from latest main (3aeea05)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Merge McNulty's AAA per-client architecture (M1-M6 phasing)
- Merge pre/post endpoint contracts addendum
- Archive both decision docs to archive/
- Cross-note Freamon (M1-M3 in flight) and Bunk (test matrix in flight)
- Capture Zack's pre/post integration directive
- Append AAA kickoff note to Kima (M6 UI pending) and Sydnor (no infra changes)
- Bump scoped-override-cascade SKILL confidence to medium (architecture approved)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Orchestration logs: Freamon (M1-M3 complete, 3d409d2), Bunk (21-test matrix complete, 6c858b9), Sydnor (M4 in-flight), Kima (M5 in-flight)
- Session log: M1-M3 shipped, test baseline 295→312 passing, M4-M5 parallel in-flight
- Merged inbox decisions into decisions.md (M1-M3 implementation status)
- Archived full specs: freamon-aaa-m1-m3-impl.md, bunk-aaa-test-matrix.md
- Updated agent histories: Freamon (M1-M3 details), Bunk (test matrix details), Sydnor (M4 scope), Kima (M5 scope)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@seiggy seiggy force-pushed the feature/apim-policy-management branch from bb4e2c0 to 24de42b Compare May 21, 2026 21:53
seiggy and others added 2 commits May 21, 2026 18:05
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ction

- Added orchestration logs for Sydnor M4 (APIM templates, commit 24de42b) and Kima M5 (admin UI, commit ec54c29)
- Added session log for M4-M5 milestone: 316 passing tests, M6 deferred
- Merged inbox decision files for Sydnor M4 and Kima M5 into decisions.md
- Archived full M4-M5 specs to decisions/archive/
- Updated all agent histories with M4-M5 completion and cross-team context
- AAA authorization layer complete: M1-M3 backend + M4 templates + M5 admin UI
- All 21 AAA tests active and passing; deployment ready

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant