Feat: AIAC Phase 1 — functional agent, UC-1 service onboarding + integration tests - #710
Conversation
Add step-by-step event and call flow diagrams for UC-1a (service on-boarding), UC-1b (realm role on-boarding), UC-2a (incremental policy update), and UC-2b (full rebuild) under a new Call Flows subsection in the Technical Addendum. Restructure the Technical Addendum: promote Key Interface Surface to a named subsection (###) and demote the five endpoint description subsections to ####, keeping Call Flows at the same ### level. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com> Signed-off-by: Oleg Blinder <olegb@il.ibm.com>
Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com> Signed-off-by: Oleg Blinder <olegb@il.ibm.com>
Incorporated Abstract, Problem Description, Problem Solution, Major Use-Cases, Component Architecture overview, and Kagenti/Keycloak/OPA Interfaces sections from ARCHITECTURE-SUMMARY.md into PRD.md. Restructured PRD layout: - Removed redundant Purpose section; promoted its design content to standalone Problem Description, Problem Solution, and Design Principles sections - Added Major Use-Cases (UC-1 through UC-4) as a top-level section - Added Component Summary table and data-flow diagram to Architecture Overview - Added Kagenti / Keycloak / OPA Interfaces section - Grouped component sections 7.1–7.8 under a single AIAC System Components parent section - Renumbered all sections 1–10 in document order Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com> Signed-off-by: Oleg Blinder <olegb@il.ibm.com>
… semantics Replace generic (read config)/(set policy) labels in both the architecture summary and PRD diagrams with descriptive italic call text matching the PDP interface endpoints. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com> Signed-off-by: Oleg Blinder <olegb@il.ibm.com>
Technology-neutral greenfield evaluation of Red Hat AMQ Broker, AMQ Streams, and AMQ Interconnect against the ten functional requirements derived from the AIAC PRD. AMQ Broker satisfies all requirements; selection guidance covers conditions where it is preferred over the PRD's NATS JetStream choice. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com> Signed-off-by: Oleg Blinder <olegb@il.ibm.com>
Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com> Signed-off-by: Oleg Blinder <olegb@il.ibm.com>
Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com> Signed-off-by: Oleg Blinder <olegb@il.ibm.com>
…l Addendum Move Call Flows before Short-Term Objectives for a more logical reading order (structure before goals). Remove the Technical Addendum wrapper, promoting Call Flows to a top-level section. Fix missing blank line before the NATS JetStream interface divider. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com> Signed-off-by: Oleg Blinder <olegb@il.ibm.com>
Signed-off-by: Anatoly Koyfman <anatoly@il.ibm.com>
Signed-off-by: Anatoly Koyfman <anatoly@il.ibm.com>
Signed-off-by: Anatoly Koyfman <anatoly@il.ibm.com>
Signed-off-by: Anatoly Koyfman <anatoly@il.ibm.com>
Reshape models, refactor Configuration and Policy to stateful class APIs based on design decisions from grilling session. Models: - Remove Assignments and Permission - Role: drop clientRole; add childRoles (list[Role]), mappedScopes (list[Scope]) - Subject: add roles (list[Role]) - Service: drop clientId, protocol, publicClient; add type (Agent/Tool), roles, scopes - Scope: drop protocol - Definition order: Subject → Role → Service → Scope with model_rebuild() calls Configuration: refactor from module-level functions to stateful Configuration class with for_realm() factory; drop get_subject_assignments, get_service_permissions, get_role_composites Policy: refactor from module-level functions to stateful Policy class with for_realm() factory; drop all composite/permission functions; rename create_service_scope → create_scope Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com> Signed-off-by: Oleg Blinder <olegb@il.ibm.com>
… PRD Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com> Signed-off-by: Oleg Blinder <olegb@il.ibm.com>
…ients
Reshape aiac.pdp.library to match the redesigned PRD (issues 1.6, 2.9,
2.10). Implementation done via TDD red-green-refactor cycles.
Models (issue 1.6):
- Remove Assignments, Permission; remove clientRole from Role; remove
clientId/protocol/publicClient from Service; remove protocol from Scope
- Add Service.type: Literal["Agent","Tool"] | None
- Add nested roles/scopes lists to Subject, Role, Service
- Add childRoles/mappedScopes to Role; call model_rebuild() for forward refs
Configuration (issue 2.9):
- Rewrite module-level functions as Configuration class with for_realm()
classmethod factory; reads AIAC_PDP_CONFIG_URL env var with fallback
- get_subjects / get_roles / get_services / get_scopes return typed lists
Policy (issue 2.10):
- Rewrite as Policy class with for_realm() factory; reads AIAC_PDP_POLICY_URL
- create_scope POSTs to /services/{id}/scopes and returns Scope
Supporting changes:
- Empty pdp/__init__.py and pdp/library/__init__.py (no re-exports at pkg root)
- Adapt read_api_from_config to new model shapes; stub out-of-scope functions
(get_subject_assignments, get_service_permissions, get_role_composites)
pending issues 3.5 / 3.7–3.11
- Rewrite test_models.py (31 tests), test_configuration.py (15 tests),
test_policy.py (8 tests) — all 54 pass
- Update show_keycloak_data.py to the new class-based API; confirmed green
against live PDP config service in kind-kagenti cluster
Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com>
Signed-off-by: Oleg Blinder <oblinder@gmail.com>
Signed-off-by: Oleg Blinder <olegb@il.ibm.com>
…dule Scopes are configuration entities, not policy entities. The library split is by domain: configuration (subjects/roles/services/scopes read+write) vs policy (composite role mappings / Rego rules). Move create_scope and its HTTP endpoint from AIAC_PDP_POLICY_URL to AIAC_PDP_CONFIG_URL. Update PRD.md to remove the read-only characterisation of the PDP Configuration Service and the configuration library module. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com> Signed-off-by: Oleg Blinder <olegb@il.ibm.com>
…d}/scopes endpoint
- Add `Configuration.create_scope(service_id, scope_name, description)` to
`aiac.pdp.library.configuration` — POSTs to the config service and returns
a typed `Scope` instance
- Strip `Policy` to a skeleton (`__init__` + `for_realm` only); scope creation
belongs to `Configuration`, not `Policy`
- Add `POST /services/{service_id}/scopes` to the PDP Configuration Keycloak
service: creates a realm-level client scope and assigns it as a default scope
to the given service in a single operation (201 on success, 502 on
KeycloakError)
- Add `pydantic` to the configuration service `requirements.txt`
- Update PRD (`pdp-configuration-service.md`) with the new endpoint spec
- Full TDD coverage: 93 unit tests pass
Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com>
Signed-off-by: Oleg Blinder <oblinder@gmail.com>
Signed-off-by: Oleg Blinder <olegb@il.ibm.com>
Replace the atomic `create_scope(service_id, scope_name, description)`
with two separate methods: `create_scope` (realm-level creation) and
`map_scope_to_service` (assigns existing scope to a service, returns
refreshed Service). Add matching `create_role` / `map_role_to_service`
methods for realm-level roles.
Update the PDP Configuration Service PRD accordingly: remove the old
atomic `POST /services/{id}/scopes`, add `POST /scopes`, `POST /roles`,
`POST /services/{id}/scopes/{scope_id}`, `POST /services/{id}/roles/{role_id}`,
and `GET /services/{id}` endpoints with Keycloak Admin API mappings and
409/502 response semantics.
Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com>
Signed-off-by: Oleg Blinder <oblinder@gmail.com>
Signed-off-by: Oleg Blinder <olegb@il.ibm.com>
Add 5 new write endpoints to the PDP Configuration Service (issue 1.9):
- GET /services/{service_id}
- POST /scopes (creates realm-level scope with protocol openid-connect)
- POST /services/{id}/scopes/{scope_id} (assigns scope as default)
- POST /roles (creates realm-level role)
- POST /services/{id}/roles/{role_id} (assigns role to service scope mappings)
All endpoints return 409 on conflict and 502 on KeycloakError.
Update Configuration library client (issue 2.9) to replace the old
create_scope(service_id, ...) with four new write methods:
- create_scope(scope_name, scope_description) → POST /scopes
- map_scope_to_service(service, scope) → POST + GET re-fetch
- create_role(role_name, role_description) → POST /roles
- map_role_to_service(service, role) → POST + GET re-fetch
Add unit tests for all 5 service endpoints (issue 2.11) and update
library configuration tests to cover the new write methods (issue 3.13).
Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com>
Signed-off-by: Oleg Blinder <oblinder@gmail.com>
Signed-off-by: Oleg Blinder <olegb@il.ibm.com>
Signed-off-by: Anatoly Koyfman <anatoly@il.ibm.com>
Extract Service Onboarding, Policy Update, and Role Update (formerly Realm Roles) into dedicated sub-PRDs under components/aiac-agent/. Trim aiac-agent.md to shared infrastructure only (NATS Consumer, Controller, Shared Module, Validate Node, Config, Error Handling). Add scoped architecture diagrams to each UC sub-PRD. Rename Realm Roles orchestrator to Role Update across all PRD documents. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com> Signed-off-by: Oleg Blinder <olegb@il.ibm.com>
aiac.apply.build → aiac.apply.policy.build POST /apply/build → POST /apply/policy/build POST /apply/rebuild → POST /apply/policy/rebuild Updated across uc2-policy-update.md, aiac-agent.md, ARCHITECTURE-SUMMARY.md, PRD.md, event-broker.md, and rag-ingest-service.md. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com> Signed-off-by: Oleg Blinder <olegb@il.ibm.com>
All AIAC components (Agent, Event Broker, PDP Interface, RAG) now use
the domain term 'role'. Keycloak-facing services translate to the
Keycloak 'realm role' concept internally at the boundary.
- NATS subject: aiac.apply.realm-role.{id} → aiac.apply.role.{id}
- HTTP path: /apply/realm-role/{id} → /apply/role/{id}
- Python dirs: realm_roles/ → roles/, realm_role/ → role/
- Prose, Mermaid labels, section headings updated across 13 files
- python-keycloak method names and Keycloak Admin API URLs unchanged
Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com>
Signed-off-by: Oleg Blinder <oblinder@gmail.com>
Signed-off-by: Oleg Blinder <olegb@il.ibm.com>
Signed-off-by: Anatoly Koyfman <anatoly@il.ibm.com>
…o aiac Signed-off-by: Anatoly Koyfman <anatoly@il.ibm.com>
Closes issues 3.11, 3.12, 3.15 (implementation) and 4.10, 4.11, 4.12 (unit tests).
- shared/state.py: TriggerContext, BaseAgentState, PDPSnapshot, Permission,
Assignments, CompositeMapping, ProposedDiff, ValidationVerdict
- shared/nodes.py: fetch_policy, fetch_domain_knowledge (ChromaDB)
- roles/role/nodes.py: fetch_pdp_state, propose_mappings, validate_mappings
(4-check: scope, existence, safety guard, auditor LLM), apply_mappings,
format_response
- roles/role/graph.py: RoleGraph compiled StateGraph
- roles/orchestrator.py: thin dispatcher for role/{id} trigger
- controller/nats_consumer.py: JetStream consumer with ack-after-await
semantics and connection-loss retry
- pdp/library/policy.py: stub add/remove_role_composites (NotImplementedError)
- test/agent/: 35 unit tests; all pass with pytest -m "not integration"
Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com>
Signed-off-by: Oleg Blinder <oblinder@gmail.com>
Signed-off-by: Oleg Blinder <olegb@il.ibm.com>
…sues 3.2, 4.1) Add FastAPI controller with four /apply/* routes dispatching to role, policy, and service orchestrators. Fix fetch_domain_knowledge to raise 503 when ChromaDB is unavailable (was silently returning []). Add unit tests for shared nodes and controller routes (20 new tests, 190 total). - controller/routes.py: FastAPI app, lifespan with NATS consumer, stub handlers for policy and service orchestrators - controller/Dockerfile + requirements.txt: python:3.12-slim base, build context aiac/src/ - shared/nodes.py: raise 503 on ChromaDB unavailability in both nodes Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com> Signed-off-by: Oleg Blinder <olegb@il.ibm.com>
Replace light pastel fills (#dbeafe, #fef9c3, #dcfce7, #fee2e2) with dark equivalents and add explicit text/stroke colors so node labels are legible in VS Code dark theme markdown preview. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com> Signed-off-by: Oleg Blinder <olegb@il.ibm.com>
The diagram file had no inbound references from PRD.md or any sub-component spec, making it an orphaned visual supplement. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com> Signed-off-by: Oleg Blinder <olegb@il.ibm.com>
Resolve the 11 findings from the follow-up CodeRabbit review:
- github_tool Dockerfile: install -r requirements.txt (was hardcoding
mcp[cli]+uvicorn, dropping the pinned bounds and httpx).
- pdp-policy-writer-opa spec: correct the outbound behaviour note
(subject_ok matches subject_role_scopes[role], target_ok matches
target_scopes[input.target]); fix the stale file tree
(aiac/pdp/library/policy.py -> aiac/pdp/policy/library/api.py); add a
note reconciling the client-UUID vs clientId identifiers used at the
onboarding vs writer layers.
- idp-configuration-service spec: reconcile the /services/{id}/roles
summary row, behaviour note, and Assumption 3 with the code, which
returns client roles PLUS aiac.managed realm roles on the service
account.
- ARCHITECTURE-SUMMARY: mark the NATS Event Broker / subscription path as
Phase 2 and the direct Controller /apply/* invocation as the Phase 1
trigger, matching event-broker.md; align the library import path with
the .api submodule convention.
- uc1-service-onboarding spec: make the focus-resolution snippet use a
default + explicit 404 (matches builder.py and the surrounding prose).
- k8s: rename the standalone pod's ConfigMap to aiac-pdp-config-standalone
to avoid clobbering the interface ConfigMap; document the deployment as
a Phase 1 local/Kind dev topology (node-local images).
Docs/specs and build config only; no source changes, unit suite unaffected.
Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com>
Signed-off-by: Oleg Blinder <oblinder@gmail.com>
Address 8 open GitHub Advanced Security (CodeQL) alerts on PR rossoctl#710: - py/stack-trace-exposure (x3, store/service/main.py): SQLite errors were echoed to clients via {"error": str(e)}. Log the exception server-side and return a generic {"error": "database error"} body instead. - py/log-injection (engine.py): strip CR/LF from service_id before logging so a hostile id cannot forge log records. - py/partial-ssrf (pdp/policy/library/api.py): URL-encode the agent_id path segment with quote(..., safe=''); also fixes routing for slash-bearing clientIds so they cannot split into extra path segments. - py/partial-ssrf (x2, store/library via keying.py): assert the base64url encoded service_id matches [A-Za-z0-9_-]+ before it reaches a request URL. - py/path-injection (rego.py slugify): assert the slug is a single [a-z0-9_]+ segment (blocks path traversal, rejects empty slugs) before it becomes a filename in the PDP Policy Writer output dir. No behaviour change for valid inputs; full unit suite (466 tests) green. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com>
Address 8 open GitHub Advanced Security (CodeQL) alerts on PR rossoctl#710: - py/stack-trace-exposure (x3, store/service/main.py): SQLite errors were echoed to clients via {"error": str(e)}. Log the exception server-side and return a generic {"error": "database error"} body instead. - py/log-injection (engine.py): strip CR/LF from service_id before logging so a hostile id cannot forge log records. - py/partial-ssrf (pdp/policy/library/api.py): URL-encode the agent_id path segment with quote(..., safe=''); also fixes routing for slash-bearing clientIds so they cannot split into extra path segments. - py/partial-ssrf (x2, store/library via keying.py): assert the base64url encoded service_id matches [A-Za-z0-9_-]+ before it reaches a request URL. - py/path-injection (rego.py slugify): assert the slug is a single [a-z0-9_]+ segment (blocks path traversal, rejects empty slugs) before it becomes a filename in the PDP Policy Writer output dir. No behaviour change for valid inputs; full unit suite (466 tests) green. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com>
…w findings Two automated checks on PR rossoctl#710 were failing: CodeQL (2 new alerts): - py/partial-ssrf (critical, pdp/policy/library/api.py): the prior quote() fix did not satisfy CodeQL. Add a regex fullmatch barrier on the encoded segment (mirroring policy/store/keying.py, which CodeQL accepts) via a new _agent_id_segment() helper used by apply_agent_policy + delete_agent_policy. - py/path-injection (high, pdp/service/policy/opa/main.py): the /health handler took out_dir as a FastAPI route parameter, which CodeQL treats as request-controlled input flowing into a filesystem path check. Resolve it from get_output_dir() inside the handler instead (it is operator config, never a request). Update TestHealth to drive REGO_OUTPUT_DIR via env. Dependency Review: - chromadb CVE-2026-45829 / GHSA-f4j7-r4q5-qw2c (critical, transitive via crewai in the github_agent demo) has no patched version (affected <= 1.5.9) and is already documented as a mitigated/accepted risk in the demo's pyproject.toml. Add it to the dependency-review-action allowlist. Full unit suite (466 tests) green. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com>
…w findings Two automated checks on PR rossoctl#710 were failing: CodeQL (2 new alerts): - py/partial-ssrf (critical, pdp/policy/library/api.py): the prior quote() fix did not satisfy CodeQL. Add a regex fullmatch barrier on the encoded segment (mirroring policy/store/keying.py, which CodeQL accepts) via a new _agent_id_segment() helper used by apply_agent_policy + delete_agent_policy. - py/path-injection (high, pdp/service/policy/opa/main.py): the /health handler took out_dir as a FastAPI route parameter, which CodeQL treats as request-controlled input flowing into a filesystem path check. Resolve it from get_output_dir() inside the handler instead (it is operator config, never a request). Update TestHealth to drive REGO_OUTPUT_DIR via env. Dependency Review: - chromadb CVE-2026-45829 / GHSA-f4j7-r4q5-qw2c (critical, transitive via crewai in the github_agent demo) has no patched version (affected <= 1.5.9) and is already documented as a mitigated/accepted risk in the demo's pyproject.toml. Add it to the dependency-review-action allowlist. Full unit suite (466 tests) green. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com>
The dependency-review check flagged json-repair@0.25.3 (transitive via crewai in the github_agent demo) for GHSA-xf7x-x43h-rpqh (high, unbounded-CPU DoS via circular JSON Schema $ref). Patched in 0.60.1. Pin it in pyproject.toml following the existing indirect-dep pattern and refresh uv.lock (also pulls minor crewai 1.15.2->1.15.8, mcp, pydantic-settings bumps from re-resolution). chromadb (CVE-2026-45829, no patched version) remains allowlisted via allow-ghsas in security-scans.yaml. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com>
Address 8 open GitHub Advanced Security (CodeQL) alerts on PR rossoctl#710: - py/stack-trace-exposure (x3, store/service/main.py): SQLite errors were echoed to clients via {"error": str(e)}. Log the exception server-side and return a generic {"error": "database error"} body instead. - py/log-injection (engine.py): strip CR/LF from service_id before logging so a hostile id cannot forge log records. - py/partial-ssrf (pdp/policy/library/api.py): URL-encode the agent_id path segment with quote(..., safe=''); also fixes routing for slash-bearing clientIds so they cannot split into extra path segments. - py/partial-ssrf (x2, store/library via keying.py): assert the base64url encoded service_id matches [A-Za-z0-9_-]+ before it reaches a request URL. - py/path-injection (rego.py slugify): assert the slug is a single [a-z0-9_]+ segment (blocks path traversal, rejects empty slugs) before it becomes a filename in the PDP Policy Writer output dir. No behaviour change for valid inputs; full unit suite (466 tests) green. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com>
…w findings Two automated checks on PR rossoctl#710 were failing: CodeQL (2 new alerts): - py/partial-ssrf (critical, pdp/policy/library/api.py): the prior quote() fix did not satisfy CodeQL. Add a regex fullmatch barrier on the encoded segment (mirroring policy/store/keying.py, which CodeQL accepts) via a new _agent_id_segment() helper used by apply_agent_policy + delete_agent_policy. - py/path-injection (high, pdp/service/policy/opa/main.py): the /health handler took out_dir as a FastAPI route parameter, which CodeQL treats as request-controlled input flowing into a filesystem path check. Resolve it from get_output_dir() inside the handler instead (it is operator config, never a request). Update TestHealth to drive REGO_OUTPUT_DIR via env. Dependency Review: - chromadb CVE-2026-45829 / GHSA-f4j7-r4q5-qw2c (critical, transitive via crewai in the github_agent demo) has no patched version (affected <= 1.5.9) and is already documented as a mitigated/accepted risk in the demo's pyproject.toml. Add it to the dependency-review-action allowlist. Full unit suite (466 tests) green. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com>
clawgenti
left a comment
There was a problem hiding this comment.
AIAC Phase 1 is a substantial, well-scoped addition — CI is all green (CodeQL, Bandit, Dependency Review, Hadolint, Trivy all pass), all 178 commits are signed off, and secrets are correctly sourced from environment variables throughout.
Two security hygiene findings noted below; no blockers.
Reviewed by clawgenti using github:pr-review
| deny-licenses: GPL-3.0, AGPL-3.0 | ||
| comment-summary-in-pr: never | ||
| # CVE-2026-45829 / GHSA-f4j7-r4q5-qw2c (chromadb, transitive via crewai): no patched | ||
| # version exists (affected <= 1.5.9, crewai pins chromadb < 1.2). The vulnerability |
There was a problem hiding this comment.
nit: allow-ghsas: GHSA-f4j7-r4q5-qw2c is scoped at the job level, so it silences the advisory for all packages in the scan, not just chromadb. The justification in the comment is sound (no fixed version, trust_remote_code not used), but worth noting if a future dep happens to share the advisory ID. Consider adding a follow-up ticket to re-evaluate once chromadb ships a patched release.
Add a non-root user (UID 10001) to the five service Dockerfiles under aiac/src/aiac, matching the authbridge/sparc-service pattern: - agent/controller - idp/service/configuration/keycloak - pdp/service/policy/keycloak - pdp/service/policy/opa - policy/store/service (chown /data for the default-path SQLite start) The two services that write to mounted volumes need fsGroup so the non-root UID can write (a mount masks the image's chown, leaving the volume root-owned). Add pod-level runAsUser/runAsGroup/fsGroup 10001 to: - policy-store-statefulset.yaml (PVC at /data) - pdp-interface-deployment.yaml (emptyDir at /rego) Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com>
|
Addressed the first finding (containers running as root) in c173113. Added a non-root user (UID 10001) to the five service Dockerfiles under Two of those services write to mounted volumes, where the image's
The demo Assisted-By: Claude (Anthropic AI) noreply@anthropic.com |
Some additional comments/security issues/suggested cleanups from Claude.Any non-must issues can be deferred to next PR but should be documented properly to be covered later. General cleanup/inconsistencies:
Container security:
Efficiency/design comments:
|
c173113 to
1490494
Compare
Record the AIAC service deployment convention in aiac/CLAUDE.md: all service images run as non-root UID 10001, and services that write to a mounted volume (policy store /data PVC, OPA writer /rego emptyDir) also need pod-level securityContext fsGroup so the kubelet chowns the volume. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com>
DCO statusThe sign-off mismatch is fixed. 218 commits were authored/committed as
0 sign-off mismatches remain. This required a force-push of Remaining DCO failure is an app limitation, not a real violation. The DCO check now reports:
The PR has 288 commits (> the 250 REST cap), and the app's GraphQL fallback isn't completing. Pushing new commits only raises the count; the API Ask for a maintainer: please either Re-run the DCO check from the Checks tab (the UI uses different auth and the fallback failure appears transient), or admin-merge / mark DCO non-required for this PR — the sign-offs themselves are now fully compliant. Assisted-By: Claude (Anthropic AI) noreply@anthropic.com |
|
Documenting my understanding of the scope of this PR and suggestions for future releases:
|
abigailgold
left a comment
There was a problem hiding this comment.
Once all must-fix comments are addressed and whatever is deferred to a future PR is well documented, I approve this PR.
Resolves the must-fix severity items from abigailgold's review: - Remove leaked AI tool-call XML fragments (</parameter>, </invoke>, </content>) accidentally committed at the end of three specs: library-policy-store.md, policy-computation-engine.md, and policy-store.md (the last not flagged but same defect class). - github_tool Dockerfile: add non-root user (USER 10001); it was running as root, inconsistent with its sibling github_agent. - Digest-pin FROM python:3.12-slim in the github_tool Dockerfile and the five src/aiac service Dockerfiles, reusing the digest already vetted in authbridge/demos/hr-cpex. (Non-root USER on the five service images was added in a prior commit.) - github-tool-deployment.yaml: add CPU/memory requests and limits. The PR description was also corrected to disclose the security-scans.yaml allow-ghsas change as a second root-level change. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com>
|
Addressed all must-fix severity findings from the two tables above in General cleanup/inconsistencies
While in there I also cleaned a third committed spec with the same leaked-XML defect that wasn't flagged: Container security
Deferred (non-must-fix)The suggestions/nits (4–8, 12–19) are intentionally out of scope for this commit and are not yet addressed. Per the review guidance, these should be tracked for a follow-up PR. Assisted-By: Claude (Anthropic AI) noreply@anthropic.com |
Resolves the suggestion-tier items from the PR rossoctl#710 review: - rossoctl#5 Docs consolidation: remove ARCHITECTURE-SUMMARY.md, which duplicated the PRD's Abstract/Problem/Solution/Use-Cases/diagram almost verbatim and carried an older (pre-compute_and_apply) call-flow. The PRD is the single spec of record. - rossoctl#12 Pod-security hardening across all k8s/ and demo manifests: pod-level runAsNonRoot + seccompProfile RuntimeDefault, container-level allowPrivilegeEscalation:false, readOnlyRootFilesystem:true, and capabilities drop ALL. Writable /tmp emptyDir added where the root FS is read-only. The demo github-agent hardens at the container level only (its injected AuthBridge sidecar runs as UID 1337) and omits readOnlyRootFilesystem (uv/litellm/crewai write caches under HOME=/app). - rossoctl#13 CPU/memory requests + limits on the agent, both pdp-interface containers, the policy-store, and the standalone idp pod. - rossoctl#14 Liveness probes on every workload (httpGet /health where exposed, tcpSocket for the Controller and demo workloads that expose none). Also updates aiac/CLAUDE.md to document the new pod-security hardening baseline (the prior note that volume-less services need no manifest securityContext is now stale). The PR description wording (rossoctl#4, the stale docs/issues/ tracker claim) was corrected directly on the PR. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com>
|
Addressed the suggestion-severity items from the review in 585b7a6, plus the PR-description wording fix. Summary of resolved vs. deferred: Resolved
Two deliberate, in-file-documented deviations on the demo Deferred (not in this pass)The remaining Assisted-By: Claude (Anthropic AI) noreply@anthropic.com |
|
Follow-up on the deferred efficiency/design item — finding 16. Reviewed it: not a real performance issue — the store writes are already bounded to one per affected service, so I'm marking it won't-fix rather than deferring. No code change needed. Assisted-By: Claude (Anthropic AI) noreply@anthropic.com |
Summary
Delivers Phase 1 of the AI-based Access Control (AIAC) Kagenti extension and the UC-1 (service onboarding) use case, addressing #645.
AIAC translates a natural-language access-control policy into concrete PDP (OPA) rules for AI agents on Kubernetes. This PR lands the full Phase 1 stack plus the integration-test ladder that proves UC-1 end-to-end by evaluating the generated Rego (Phase 1 explicitly defers live enforcement/traffic).
What's included
Core services & library (
aiac/src/aiac/, all Python 3.12,idp/pdp/policynamespace split):aiac.idp.configuration) — Keycloak Admin REST proxy exposing subjects/roles/services/scopes with per-service enrichment; stamps theaiac.managedprovisioning marker.{slug}.inbound.rego+{slug}.outbound.rego(the Phase 1 Interface-Pod deployment).ServicePolicyModel/AgentPolicyModelstate; SPM-centric.aiac.policy.computation) — in-process library; singlecompute_and_apply(rules)entry point, additive merge with drift-GC + authoritativedecommission()offboard.aiac.policy.model) —PolicyRule,ServicePolicyModel,AgentPolicyModel,PolicyModel.AIAC Agent (
aiac.agent) — FastAPI Controller dispatching/apply/*to UC sub-agents:kagenti.io/typelabel, discovers capabilities (AgentCard for agents; MCPtools/listfor tools), provisions roles/scopes into Keycloak, runs the Policy Rules Builder (PRB, LLMtemperature=0), and calls the PCE.Demo scenario workloads (
aiac/demo/) —github-agent(A2A, source + issue skills) and a simplifiedgithub-toolMCP server, with their k8s manifests. These are the workloads onboarded by the integration tests.Kubernetes manifests (
aiac/k8s/) — Interface Pod, Policy Store StatefulSet, Agent deployment (Phase 1).Specs —
aiac/docs/specs/(master PRD + per-component + integration-test specs).Testing
.venv/bin/pytest test/ -m "not integration"(no--ignoreflags needed after the Wave 3 SPM migration).aiac/test/integration/,@pytest.mark.integration,opa-gated) —uc1-onboarding-pipeline: drives the real UC-1 agent (POST /apply/service/{id}) against really-deployed workloads and asserts the generated Rego withopa eval, computing verdicts fromscenario_uc1.py(the oracle):policy-pipelineandpdp-policy-writerstandalone launcher integration tests.Out of scope (Phase 1)
Live trigger path / NATS Event Broker, live enforcement & token exchange, writing Rego to the
AuthorizationPolicyCR, the RAG knowledge base, and UC-2/UC-3 — all deferred to later phases per the PRD.Notes for reviewers
aiac/. There are two root-level changes: a newpyrightconfig.json(tooling config), and a modification to.github/workflows/security-scans.yamlthat adds a 5-lineallow-ghsasexception for a chromadb/crewai transitive CVE (with a documented in-file justification). The latter is a security-policy exception and is the more reviewer-relevant of the two — please review it explicitly.aiac/docs/specs/PRD.mdandaiac/docs/specs/integration-test/uc1-onboarding-pipeline.md.Addresses #645 (Phase 1 implementation + integration tests; runnable demo flow to follow in a separate PR).
Assisted-By: Claude (Anthropic AI) noreply@anthropic.com