Feat: AIAC Event Broker + Keycloak SPI listener (phase 2, PR 2) - #753
Feat: AIAC Event Broker + Keycloak SPI listener (phase 2, PR 2)#753oblinder wants to merge 385 commits into
Conversation
Signed-off-by: Anatoly Koyfman <anatoly@il.ibm.com>
Signed-off-by: Anatoly Koyfman <anatoly@il.ibm.com>
…odel Split Policy Management Service into three components: - Policy Store (aiac.policy.store): SQLite-backed CRUD service, K8s rename aiac-policy-store / aiac-policy-store-service:7074 / AIAC_POLICY_STORE_URL - Policy Computation Engine (aiac.policy.computation): pure library module, compute_and_apply(rules) — IdP resolution, additive merge, PDP push - Policy Model (aiac.policy.model): canonical, dependency-free Pydantic models with typed Role/Scope/Service fields and id-only hash/eq New component PRDs: policy-store.md, policy-computation-engine.md, policy-model.md Renamed library PRDs: library-policy-store.md (was library-state.md, AIAC_POLICY_STORE_URL) library-pdp-policy.md (was library-pdp.md policy section, aiac.pdp.policy.library) Updated in-place: library-idp.md — namespace aiac.idp.configuration, remove mappedScopes/get_roles scope-fetch, add get_services_by_role + get_services_by_scope PRD.md — component table, call flows, dependencies, arch decisions, deployment Deleted deprecated: policy-management-service.md, library-state.md, library-pdp.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>
… compute_and_apply(rules) - Rename PolicyBuilderGraph → SharedApplyGraph; apply_policy → apply_rules - Replace policy_model: PolicyModel | None state field with rules: list[PolicyRule] - Remove TBD Policy sub-agent / Policy Builder sub-agent; shared apply node now delegates all Policy Store ↔ PDP Policy Writer coordination to PCE - Add AIAC_POLICY_STORE_URL to config table; fix module paths to aiac.idp.configuration.api - Remove apply_diff from individual sub-agent node lists (owned by shared apply) - Update use cases note to reference policy-computation-engine.md Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com> Signed-off-by: Oleg Blinder <olegb@il.ibm.com>
…ion; remove mappedScopes; add PCE query methods - Issue 1.11: move library to aiac/src/aiac/idp/configuration/, update all non-frozen import sites - Issue 8.3: remove Role.mappedScopes, drop /scopes call in get_roles(), add get_services_by_role() and get_services_by_scope() - Issue 8.4: unit tests for new methods and mappedScopes removal (260 tests pass) - Fix show_keycloak_data.py: update imports and remove mappedScopes references Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com> Signed-off-by: Oleg Blinder <olegb@il.ibm.com>
- Add RAG Ingest → ChromaDB arrowhead in PRD.md high-level diagram - Replace arch diagram in ARCHITECTURE-SUMMARY with PRD version (Policy Store Pod, Policy Compute Engn box, RAG Ingest ──► ChromaDB) - Update component table: 7 → 8 entries; Policy Management Service → Policy Store (#3); add Policy Computation Engine (#4); update library module paths and descriptions throughout 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>
… + PCE direct call - Sub-agents now emit tuple[list[Role], list[Scope]] instead of list[PolicyRule] - New shared Policy Rules Builder (agent/shared/policy_rules_builder/) converts tuple to list[PolicyRule]; Controller calls PCE directly with the rules - Remove shared apply node (agent/shared/apply/) - Remove UC2/UC3 Orchestrators; Controller dispatches directly to Build/Rebuild/Role sub-agents - UC1 Orchestrator retained for two-step Service Provision pipeline - Update top-level Mermaid diagram accordingly 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>
Remove shared/apply/ section and all stale orchestrator framing. Add policy_rules_builder/ TBD stub with Validate Node checks moved into it. Update dispatch table, Controller responsibilities, Shared Module diagram and BaseAgentState, File Structure tree, and Endpoints table to reflect the new flow: sub-agent → tuple[list[Role], list[Scope]] → PRB → list[PolicyRule] → Controller → compute_and_apply(rules) (PCE) Only UC1 (Service Onboarding) retains an Orchestrator; UC2/UC3 are dispatched directly by the Controller. 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>
…ract PRB to sub-PRD - Remove Shared Module section: BaseAgentState, PDPSnapshot, ValidationVerdict, shared/nodes.py spec — all stale or incorrect - Remove LLM Integration section - Extract Policy Rules Builder full spec to aiac-agent/policy-rules-builder.md (nodes, PRBState, ValidationVerdict, Validate Node diagram, LLM integration stub) - File tree: remove onboarding/policy/ subtree; rename propose_diff/validate_* nodes to propose_roles_scopes; drop AUDITOR_SYSTEM from sub-agent prompts.py - Simplify shared/ to TBD stub pending PRB grill 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>
- Remove individual files; keep folder structure only - Group sub-agents under uc/ folder - Rename roles/ -> role_update/ (flat, no sub-hierarchy) - Replace shared/ with policy_rules_builder/ 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>
- Sub-agent output changed from tuple to list[tuple[list[Role], list[Scope]]] - Controller now fans PRB over list, merges rules, makes single compute_and_apply call - Mermaid diagram rewired: sub-agents → CTRL → PRB → CTRL → PCE (no direct sub-agent→PRB edges) - CO subgraph adds Service Policy Update node (sequences provision → service_policy) - Endpoints section: removed JSON response bodies; replaced with bare HTTP status paragraph - Controller bullet points updated to describe fan-PRB-over-list flow - Use Cases table: added Notes column with UC1 sequencing detail; footer note updated - File structure tree: onboarding/ now shows orchestrator.py + service_policy/; annotations added - Error Handling: appended bare-error propagation sentence - PRB path updated: agent/shared/policy_rules_builder/ → agent/policy_rules_builder/ 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>
- UC1: two-stage Orchestrator (Service Provision LLM + Service Policy Update deterministic), aiac.idp.configuration.api throughout, replay-safety note, self-exclusion logic, tool/agent tuple packaging - UC2: TBD stub with triggers and PRB→PCE pipeline stub; internal design deferred - UC3: single deterministic path, one-element list[tuple], PRB picks relevance, PCE deletes stale rules All diagrams: sub-agent → Controller → PRB → Controller → PCE (no sub-agent→PRB edge). policy-rules-builder.md 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>
…olicy 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>
- Structure: LangGraph StateGraph (graph internals TBD) - Two entry points: build_role_rules(role, scopes) and build_scope_rules(roles, scope) - PRB fetches its own ChromaDB context (both collections) - No realm parameter, no trigger type in input state - Error contract: raises on LLM/ChromaDB failure - Dedup owned by PCE - UC dispatch: UC3 -> build_role_rules, UC1 -> both (TBD), UC2 -> TBD 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>
…gents Each sub-agent (UC1 Service Policy, UC2 Build, UC3 Role) now calls the PRB directly, merges results internally, and returns list[PolicyRule] to the Controller. The Controller's role shrinks to: dispatch → receive list[PolicyRule] → call PCE. UC2 Rebuild delegates to Build. 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>
GET /services/{id}/roles and POST /services/{id}/roles/{role_id} use
the service account approach (get_client_service_account_user →
get_realm_roles_of_user / assign_realm_roles), not the client-scope
mapping API that the spec previously described.
GET /roles/{role_name}/scopes uses get_all_roles_of_client_scope +
realmMappings extraction, not get_realm_roles_of_client_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>
…e tests and smoke test - Add __hash__/__eq__ (id-only) to Role, Service, Scope in idp/configuration/models.py - Remove set_service_type() and unused Literal import from idp/configuration/api.py - Add TestHashAndEquality (15 tests) to test/pdp/library/test_models.py - Replace TestSetServiceType with TestSetServiceTypeRemoved in test/pdp/library/test_configuration.py - Add TestListServiceScopes and extend TestListServiceRoles in test/pdp/service/configuration/keycloak/test_main.py - Add get_services_by_role/get_services_by_scope sections to smoke test show_keycloak_data.py 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>
- policy-model.md: add subject_roles dict[Subject, list[Role]] field; extend Subject hashability (__hash__/__eq__ by id); update usage example and testing decisions - library-idp.md: add Subject to hashability set; add get_subjects_by_role(role) -> list[Subject] to Configuration class - idp-configuration-service.md: add GET /subjects?role_id= filtered variant (role name resolution via get_realm_role_by_id, enriched subject list) - policy-computation-engine.md: rewrite algorithm to 7 steps — composite role flattening, source_roles population (gap fix), subject_roles population, realm-level role semantics; update deps and testing decisions 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 Subject.__hash__/__eq__ (id-only, type(self) guard)
- Add Configuration.get_subjects_by_role(role) to IdP library
- Add role_id query param to GET /subjects in IdP configuration service
- Restructure test/pdp/{library,service/configuration} -> test/idp/
to mirror src/aiac/idp/ layout
- Update CLAUDE.md test command and smoke test path
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: Oleg Blinder <oblinder@gmail.com> Signed-off-by: Oleg Blinder <olegb@il.ibm.com>
…y_role - TestSubjectHashability: id-only hash/eq, cross-type inequality, dict key usage - TestGetSubjectsByRole (library): happy path, empty list, non-2xx error, realm forwarded - TestGetSubjectsByRole (service): 2-subject enrichment, empty members, 502 on each Keycloak phase error, enrichment shape, missing realm -> 422, unfiltered 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>
…yModel, PolicyModel - Create aiac/src/aiac/policy/model/models.py with three Pydantic models - Use field_serializer/field_validator for model-keyed dicts (source_roles, scope_targets, subject_roles) to work around Pydantic v2 unhashable-dict-key limitation during model_dump()/model_validate() round-trips - All models use ConfigDict(extra='ignore') - Add 19 unit tests covering construction, ValidationError, serialization, round-trip, hash/eq for all four IdP types, and extra-field suppression 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>
…nit tests
- Add aiac.policy.store.service FastAPI service (port 7074)
- In-memory cache as serving layer; write-through to SQLite
- Endpoints: GET/POST/DELETE /policy and /policy/agents/{id}, GET /health
- 502 on SQLite write failure; 503 on health check failure
- AGENTPOLICY_DB_PATH defaults to /data/policy_model.db
- 18 unit tests using SQLite :memory: seam (all green)
- Update policy-store PRD to reflect policy_model.db filename
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>
Implements aiac.policy.store.library (issue 8.7): - aiac/src/aiac/policy/store/library/api.py with six module-level functions: get_policy, get_agent_policy, apply_policy, apply_agent_policy, delete_agent_policy, delete_policy - Models imported from aiac.policy.model.models - AIAC_POLICY_STORE_URL env var, default http://127.0.0.1:7074 - Non-2xx responses raise RuntimeError Adds unit tests (issue 8.8): - aiac/test/policy/store/library/test_api.py - 13 tests covering success and error cases for all six functions plus URL fallback; all HTTP calls mocked 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>
…ter-service in PDP Policy Writer OPA spec 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>
Reviewer OsherElhadad flagged three blocking issues (plus CodeQL alert rossoctl#179): 1. _patch_watsonx_for_reasoning_models was unconditional — it applied to every WatsonX deployment including the default mistral-large-2512, which supports response_format natively. That silently regressed structured output for existing users. Gate the patch behind a new SPARC_SCHEMA_IN_PROMPT=true setting (Settings.schema_in_prompt); the default path is now unchanged. 2. All three _patch_* helpers rebound methods on the shared ALTK class without a re-entry guard. ReflectionEngine caches components per track and lazily builds them, so a track switch would wrap the already-wrapped method — retry counts multiplied and debug lines duplicated on every subsequent call. Add _sparc_patched_reasoning / _sparc_patched_retry / _sparc_patched_debug sentinel attributes; each _patch_* no-ops if its sentinel is already set. 3. engine.reflect logged raw tool arguments at INFO. Args are caller-controlled — embedded newlines let a caller forge log lines (CodeQL alert rossoctl#179) — and can carry payloads (PII, payment ids, etc.). The same hunk had also dropped session_id/track from INFO. Restore session_id and track at INFO alongside tool/decision/score, and log args only at DEBUG when SPARC_LOG_REQUESTS=true. Also addresses smaller items from the same review: - tests/test_haiku_empty_response.py: replaced production PII in the conversation fixture (user id, names, DOBs, payment id, reservation ids) with synthetic values; gated both live-LLM probes behind pytest.skipif so they only run when RUN_HAIKU_TESTS=1 plus OAIKEY/OAIBASE are set (matches the reviewer's suggested opt-in path). - tests/test_providers.py: added three deterministic unit tests — retry wrapper recovers after two ValueError empty-response failures, retry wrapper re-raises unrelated ValueErrors, and all three patches are idempotent under repeat application. No credentials or network required; fills in the coverage gap the reviewer noted for the retry and schema-injection wrappers. Signed-off-by: Vitaly Zabershinsky <VITALYZ@il.ibm.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com>
…_ARG_KEYS These two env vars were introduced by PR rossoctl#738 (merged 2026-08-10) but never added to the sparc-service README's Configuration table. Documenting them here so operators discover them without having to read settings.py. Not touched here (not on main yet): SPARC_SKIP_TOOLS, SPARC_DEBUG_LLM, and SPARC_SCHEMA_IN_PROMPT — those arrive with PR rossoctl#739, and will be documented in a follow-up PR once that merges. Signed-off-by: Vitaly Zabershinsky <VITALYZ@il.ibm.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com>
Bumps [rojopolis/spellcheck-github-actions](https://github.com/rojopolis/spellcheck-github-actions) from 0.63.0 to 0.64.0. - [Release notes](https://github.com/rojopolis/spellcheck-github-actions/releases) - [Changelog](https://github.com/rojopolis/spellcheck-github-actions/blob/master/CHANGELOG.md) - [Commits](rojopolis/spellcheck-github-actions@e619e00...26a39cd) Signed-off-by: Oleg Blinder <oblinder@gmail.com> --- updated-dependencies: - dependency-name: rojopolis/spellcheck-github-actions dependency-version: 0.64.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [docker/login-action](https://github.com/docker/login-action) from 4.2.0 to 4.6.0. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](docker/login-action@650006c...dbcb813) Signed-off-by: Oleg Blinder <oblinder@gmail.com> --- updated-dependencies: - dependency-name: docker/login-action dependency-version: 4.6.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…ssoctl#748) * build(deps): Bump github/codeql-action/init from 4.37.4 to 4.37.6 Bumps [github/codeql-action/init](https://github.com/github/codeql-action) from 4.37.4 to 4.37.6. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](github/codeql-action@f205ea1...5595cca) Signed-off-by: Oleg Blinder <oblinder@gmail.com> --- updated-dependencies: - dependency-name: github/codeql-action/init dependency-version: 4.37.6 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): Bump github/codeql-action from 4.37.4 to 4.37.6 Signed-off-by: Evaline Ju <69598118+evaline-ju@users.noreply.github.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: Evaline Ju <69598118+evaline-ju@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Evaline Ju <69598118+evaline-ju@users.noreply.github.com>
Bumps [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) from 4.37.0 to 4.37.6. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](github/codeql-action@99df26d...5595cca) Signed-off-by: Oleg Blinder <oblinder@gmail.com> --- updated-dependencies: - dependency-name: github/codeql-action/upload-sarif dependency-version: 4.37.6 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Address PR rossoctl#752 review feedback: - opa-kind-enable.sh hardcoded the bundle_url namespace to rossoctl-system on both OPA legs, silently breaking the RELEASE_NAMESPACE override. Restore ${RELEASE_NAMESPACE} (the heredoc is unquoted, so it expands). - Add an inline comment at the jwt.ParseInsecure call site noting the decoded subject is used for delegation provenance only, never for an auth decision. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com>
…client) - opa-kind-driver.sh: guard mint_token's password==username grant with a DEV ONLY comment so it is not cargo-copied into staging/production. - rego.py: emit a Rego comment before agent_role_scopes noting it is informational/debugging only and not referenced by allow. - opa/requirements.txt: pin the kubernetes client to the tested major (>=36.0.3,<37) now that the writer mutates cluster state. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com>
Signed-off-by: Oleg Blinder <oblinder@gmail.com> # Conflicts: # aiac/k8s/pdp-interface-deployment.yaml # aiac/src/aiac/pdp/service/policy/opa/rego.py # aiac/src/aiac/pdp/service/policy/opa/requirements.txt
Kagenti was renamed to Rosso; the upstream dev guide moved to rossoctl/rossoctl/blob/main/docs/dev-guide.md. Update the AIAC CLAUDE.md external-reference entry (name, URL) and note the disabled-by-default ROSSOCTL_FEATURE_FLAG_<NAME> requirement. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com>
|
Important Review skippedToo many files! This PR contains 173 files, which is 73 over the limit of 100. To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch. Upgrade to a paid plan to raise the limit. This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (3)
📒 Files selected for processing (173)
You can disable this status message by setting the Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Dependency Review flagged aiohttp 3.14.1 (transitive) in the demo github-agent lockfile for GHSA-cq5v-8q36-5273 — a high-severity out-of-bounds heap read in the C HTTP response parser (affected <= 3.14.2, fixed in 3.14.3). Add an indirect floor pin (matching the existing indirect-CVE-pin pattern) and regenerate uv.lock. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com>
The Dependency Review CI check flagged cryptography 48.0.1 in the github_agent demo lockfile for GHSA-g6cj-pr64-35w5 (CVE-2026-69247), a PKCS#7 EnvelopedData Bleichenbacher oracle (high severity, affected < 50.0.0). Raise the indirect pin from >=48.0.0,<49 to >=50.0.0 and regenerate uv.lock (48.0.1 -> 50.0.0). No transitive dependency caps cryptography below 50, so the resolve is clean. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com>
Dependency Review flagged the provided-scope Keycloak server APIs in aiac/keycloak-spi at 26.5.2 for four advisories: - GHSA-x4p7-7chp-64hq (high) unauthorized auth via disabled SAML IdP - GHSA-q35r-vvhv-vx5h (mod) UMA 2.0 permission-ticket info disclosure - GHSA-rr5q-3xwr-f323 (mod) improper validation of specified quantity - GHSA-4q93-v92x-p89f (mod) incorrect authorization All four are fixed in 26.6.3. Raise the single keycloak.version property (all four keycloak-* deps derive from it) from 26.5.2 to 26.6.3. These deps are provided-scope (supplied by the Keycloak runtime, only jnats is shaded into the provider jar), so this pins the compile-time API to a patched line. Minor bump within 26.x against the stable EventListenerProviderFactory SPI; the Java module is not built in this repo's CI (only Dependency Review parses the pom). Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com>
Dependency Review flagged the provided-scope Keycloak server APIs in aiac/keycloak-spi. Split the remediation by whether a fix exists: Fixed by a version bump -> bump keycloak.version 26.5.2 -> 26.6.4 (and align the Dockerfile KEYCLOAK_IMAGE base tag, previously still 26.5.2, so the provider compiles against and runs on the same patched line). 26.6.4 clears GHSA-x4p7-7chp-64hq, GHSA-q35r-vvhv-vx5h, GHSA-rr5q-3xwr-f323, GHSA-4q93-v92x-p89f and GHSA-32h4-44jj-c5vx. No released fix -> allow-list in security-scans.yaml, mirroring the existing chromadb (GHSA-f4j7-r4q5-qw2c) precedent: GHSA-wcvj-vpvw-9rr5, GHSA-p3v8-fm5p-v84h, GHSA-q6h7-xxp7-7429 These are Keycloak *server* advisories (affected <= 26.6.4, patched 'None'); they are code we do not ship (only jnats is shaded into the provider jar) and are remediated operationally by patching the Keycloak deployment, so they cannot be closed by a dependency bump. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com>
Dependency Review flagged cryptography 49.0.0 in aiac/uv.lock for GHSA-g6cj-pr64-35w5 (CVE-2026-69247, PKCS#7 Bleichenbacher oracle, high, affected < 50.0.0) once the github_agent lock was fixed. It is an unconstrained transitive dependency, so 'uv lock --upgrade-package cryptography' moves it 49.0.0 -> 50.0.0 with no other changes. Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com> Signed-off-by: Oleg Blinder <oblinder@gmail.com>
Move aiac/docs/opa-kind-runbook.md and scripts/opa-kind-{enable,restore,driver}.sh
into aiac/k8s/, and update every reference to their old locations across
CLAUDE.md, the runbook itself, and the integration test suite.
Signed-off-by: Oleg Blinder <oblinder@gmail.com>
admin_token() hardcodes the Keycloak master realm admin/admin credentials with no caveat, unlike mint_token()'s existing DEV ONLY guard. Add the same warning so the seeded Kind-cluster default is never cargo-copied into a staging/production script. Signed-off-by: Oleg Blinder <oblinder@gmail.com>
Signed-off-by: Oleg Blinder <oblinder@gmail.com>
Summary
Follow-up to #752 in the series toward #646 (AIAC phase 2 — platform
integration). This PR lands the Event Broker consumer and the Keycloak
SPI event-listener — the plumbing for event-driven onboarding — as
implemented-but-inactive code. Nothing is wired live yet: the NATS broker
and the Keycloak SPI listener are both opt-in deployments, so with the default
manifests no events are produced or consumed. A later PR completes the live
Keycloak → Event Broker → AIAC Agent integration.
What's in this PR (delta on top of #752)
Event Broker — NATS JetStream consumer
aiac/src/aiac/agent/eventbus/consumer.py+stream.py: a durableaiac-agent-consumerqueue-group consumer that mirrors the Controller's/apply/*HTTP routes — on each message it runs the same use-case handler +compute_and_applysequence and awaits completion before acking.backoff (broker down at boot is waited out, not crashed), indefinite
reconnect, sync handlers offloaded via
asyncio.to_threadunder a lock tokeep processing serial without blocking the loop.
max_deliver=5) the consumerrepublishes to
aiac.apply.dlqand terminates the message (JetStreamWorkQueue has no native dead-letter routing).
aiac/src/aiac/agent/init/wait_and_provision.py: init-time provisioning helper.aiac/k8s/event-broker-deployment.yaml: NATS deployment (opt-in;imagePullPolicy: Never, side-loaded like the other AIAC manifests).Keycloak SPI event-listener (Java) — Keycloak integration code, not yet wired
aiac/keycloak-spi/: a KeycloakEventListenerProviderFactorySPI that mapsKeycloak events → the minimal
{id}subject payload and best-effort-publishesto NATS (
AiacEventListenerProvider,SubjectMapper, Dockerfile, Makefile,pom.xml, README) +SubjectMapperTest.Docs & specs
aiac/docs/specs/components/keycloak-spi-listener.md— new component PRD(issue feat: Allow route based TARGET_AUDIENCE configuration #69): event→subject mapping, minimal payload, best-effort publish
semantics, config, build/deploy, test seam.
event-broker.md,aiac-agent.md,PRD.md— DLQ corrected toconsumer-republish, shipped consumer modules named, section wiring.
aiac/CLAUDE.md— external-reference update: the upstream dev guide movedfrom Kagenti to the Rosso Developer Guide
(
rossoctl/rossoctl/blob/main/docs/dev-guide.md).Tests
aiac/test/agent/eventbus/+aiac/test/agent/init/: dispatch routing,await-before-ack ordering, clean lifespan cancellation, connect-failure
backoff, dotted-role subject routing.
Testing
.venv/bin/pytest test/ -m "not integration"→ 492 passed (includes thenew eventbus/init tests). Integration tests deselected (need a live cluster).
pre-commit run --files <delta>→ all hooks pass on the changed files.Pre-PR / dev-guide notes
disabled by default. This feature is disabled by deployment — the consumer
code runs in the Controller lifespan but has nothing to consume until the
(opt-in) NATS broker and Keycloak SPI listener are deployed, which the default
manifests do not do. The follow-up integration PR will wire it live.
not because of a missing/invalid sign-off — every commit is properly
signed. Its own summary says it "could not be evaluated because the complete
pull request commit list could not be retrieved" (GitHub returned 250 commits
from the REST API and the GraphQL fallback did not complete). This PR's range
is ~378 commits only because it's stacked on the unmerged Feat: AIAC OPA plugin integration + live enforcement (phase 2, PR 1) #752 and carries
its full history. Once Feat: AIAC OPA plugin integration + live enforcement (phase 2, PR 1) #752 merges and this rebases onto
main, the countdrops well under the 250-commit limit and DCO evaluates cleanly. No history
rewrite is needed.
Related
Part of #646. Follow-up to #752.
Assisted-By: Claude (Anthropic AI) noreply@anthropic.com