From e774166ff7be87620a25d5bc41b05fab5ea60cf8 Mon Sep 17 00:00:00 2001 From: IBRAHIM IBRAHIM <66755652+Ibrahim2595@users.noreply.github.com> Date: Sun, 19 Jul 2026 00:33:02 -0400 Subject: [PATCH 1/2] =?UTF-8?q?=E2=9A=A0=EF=B8=8F=20Rename=20Kagenti=20?= =?UTF-8?q?=E2=86=92=20Rossoctl=20across=20kagenti-extensions=20(=E2=86=92?= =?UTF-8?q?=20rossocortex)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Full content rename Kagenti → Rossoctl. Repo renamed kagenti-extensions → rossocortex; all 1582 case-insensitive `kagenti` references updated; grep is clean. Changes: - Brand / prose / comments: Kagenti → Rossoctl - Go modules (8): github.com/kagenti/kagenti-extensions/... → github.com/rossoctl/rossocortex/... (module dirs + internal replace directives) - External dep: github.com/kagenti/context-guru → github.com/rossoctl/context-guru (renamed in lockstep per playbook §3; see caveat below) - Cross-repo refs: kagenti-operator → operator, agent-examples → examples, kagenti/kagenti → rossoctl/rossoctl - CODEOWNERS @kagenti/* → @rossoctl/*; CI reusable-workflow refs kagenti/.github → rossoctl/.github - Python dist/console-script kagenti-sparc-service → rossoctl-sparc-service - Env vars KAGENTI_* → ROSSOCTL_* - Runtime contracts (this repo's manifests/samples): CRD group agent.kagenti.dev → agent.rossoctl.dev, labels kagenti.io/* → rossoctl.io/*, namespace kagenti-system → rossoctl-system, SPIFFE kagenti.local → rossoctl.local, Keycloak realm kagenti → rossoctl, kagenti-controller-manager → rossoctl-controller-manager Verification: - pytest tests/ (excl e2e): 12 passed (unchanged from baseline) - ruff v0.9.10: 4 pre-existing errors, unchanged (none introduced) - go build: authbridge-cpex + echo/finance-sparc/ibac demos build clean - authlib/abctl/authbridge-envoy/authbridge-proxy fail to build ONLY on github.com/rossoctl/context-guru (repo not yet published) — the expected cross-repo module-path break (playbook §4). Verified via a temporary `replace` that authlib's own code compiles; resolves once context-guru is renamed + republished and `go mod tidy` is re-run. Related to #1972 Assisted-By: Claude Opus 4.8 Signed-off-by: IBRAHIM IBRAHIM <66755652+Ibrahim2595@users.noreply.github.com> --- .claude/skills/demo.md | 24 +-- .claude/skills/orchestrate/SKILL.md | 8 +- .claude/skills/orchestrate:ci/SKILL.md | 14 +- .claude/skills/orchestrate:plan/SKILL.md | 6 +- .claude/skills/orchestrate:precommit/SKILL.md | 4 +- .claude/skills/orchestrate:replicate/SKILL.md | 2 +- .claude/skills/orchestrate:review/SKILL.md | 4 +- .claude/skills/orchestrate:scan/SKILL.md | 10 +- .claude/skills/orchestrate:security/SKILL.md | 2 +- .claude/skills/skills:validate/SKILL.md | 12 +- .claude/skills/skills:write/SKILL.md | 12 +- .github/CODEOWNERS | 10 +- .github/codeql/codeql-config.yml | 2 +- .github/spellcheck/.wordlist.txt | 6 +- .github/workflows/pr-verifier.yml | 2 +- .github/workflows/project.yml | 6 +- .github/workflows/self-assign.yml | 6 +- .github/workflows/stale.yaml | 6 +- .gitignore | 2 +- CLAUDE.md | 32 ++-- CONTRIBUTING.md | 12 +- LOCAL_TESTING_GUIDE.md | 166 +++++++++--------- Makefile | 2 +- README.md | 16 +- SECURITY.md | 2 +- aiac/docs/specs/ARCHITECTURE-SUMMARY.md | 12 +- aiac/docs/specs/PRD.md | 34 ++-- .../aiac-agent/uc1-service-onboarding.md | 18 +- .../components/idp-configuration-service.md | 2 +- .../docs/specs/components/keycloak-service.md | 2 +- aiac/docs/specs/components/library-idp.md | 6 +- .../components/pdp-policy-keycloak-service.md | 6 +- .../specs/components/pdp-policy-writer-opa.md | 4 +- aiac/docs/specs/demo/github-agent.md | 26 +-- aiac/docs/specs/demo/github-tool.md | 32 ++-- .../specs/integration-test/policy-pipeline.md | 2 +- .../uc1-onboarding-pipeline.md | 32 ++-- authbridge/CLAUDE.md | 38 ++-- authbridge/README.md | 26 +-- authbridge/authlib/README.md | 6 +- authbridge/authlib/auth/auth.go | 10 +- authbridge/authlib/auth/auth_test.go | 10 +- authbridge/authlib/auth/result.go | 2 +- authbridge/authlib/config/config.go | 6 +- authbridge/authlib/config/config_test.go | 6 +- authbridge/authlib/go.mod | 4 +- authbridge/authlib/go.sum | 4 +- .../listener/e2e/placeholder_e2e_test.go | 14 +- .../authlib/listener/extauthz/server.go | 4 +- .../authlib/listener/extauthz/server_test.go | 14 +- .../listener/extproc/mcpreject_test.go | 2 +- .../listener/extproc/placeholder_test.go | 2 +- authbridge/authlib/listener/extproc/server.go | 12 +- .../authlib/listener/extproc/server_test.go | 22 +-- .../authlib/listener/extproc/skiphost_test.go | 10 +- .../forwardproxy/mcp_sse_repro_test.go | 8 +- .../forwardproxy/mcp_sse_stream_test.go | 4 +- .../authlib/listener/forwardproxy/server.go | 18 +- .../listener/forwardproxy/server_test.go | 16 +- .../listener/forwardproxy/session_pin_test.go | 4 +- .../listener/forwardproxy/skiphost_test.go | 8 +- .../listener/forwardproxy/streaming_test.go | 2 +- .../tlsbridge_integration_test.go | 6 +- .../listener/forwardproxy/transparent.go | 6 +- .../listener/forwardproxy/transparent_test.go | 6 +- authbridge/authlib/listener/httpx/render.go | 2 +- .../authlib/listener/httpx/render_test.go | 2 +- .../internal/tlssniff/listener_test.go | 2 +- .../listener/reverseproxy/finisher_test.go | 4 +- .../listener/reverseproxy/placeholder_test.go | 2 +- .../listener/reverseproxy/recording_test.go | 4 +- .../authlib/listener/reverseproxy/server.go | 14 +- .../listener/reverseproxy/server_test.go | 12 +- .../listener/reverseproxy/streaming_test.go | 2 +- .../authlib/listener/skiphost/skiphost.go | 2 +- .../listener/skiphost/skiphost_test.go | 12 +- .../transparentproxy/origdst_linux.go | 2 +- authbridge/authlib/llmclient/README.md | 2 +- authbridge/authlib/llmclient/client_test.go | 2 +- authbridge/authlib/observe/statserver.go | 10 +- authbridge/authlib/observe/statserver_test.go | 4 +- authbridge/authlib/pipeline/action_test.go | 12 +- authbridge/authlib/pipeline/content.go | 2 +- authbridge/authlib/pipeline/content_test.go | 2 +- authbridge/authlib/pipeline/context.go | 2 +- authbridge/authlib/pipeline/schema.go | 4 +- authbridge/authlib/pipeline/session_test.go | 2 +- .../authlib/pipeline/sharedstore_test.go | 4 +- authbridge/authlib/pipeline/snapshot_test.go | 6 +- .../authlib/plugins/a2aparser/plugin.go | 8 +- .../authlib/plugins/a2aparser/plugin_test.go | 4 +- .../plugins/a2aparser/streaming_test.go | 2 +- .../authlib/plugins/contextguru/build_test.go | 6 +- .../authlib/plugins/contextguru/plugin.go | 20 +-- .../plugins/contextguru/plugin_test.go | 2 +- authbridge/authlib/plugins/cpex/README.md | 2 +- authbridge/authlib/plugins/cpex/cmf_a2a.go | 2 +- .../authlib/plugins/cpex/cmf_a2a_test.go | 2 +- authbridge/authlib/plugins/cpex/cmf_body.go | 2 +- .../authlib/plugins/cpex/cmf_body_test.go | 2 +- .../authlib/plugins/cpex/cmf_inference.go | 2 +- .../plugins/cpex/cmf_inference_test.go | 2 +- authbridge/authlib/plugins/cpex/config.go | 4 +- authbridge/authlib/plugins/cpex/manager.go | 2 +- .../authlib/plugins/cpex/manager_cpex.go | 4 +- .../authlib/plugins/cpex/manager_test.go | 2 +- authbridge/authlib/plugins/cpex/plugin.go | 6 +- .../authlib/plugins/cpex/plugin_test.go | 2 +- authbridge/authlib/plugins/ibac/judge.go | 2 +- authbridge/authlib/plugins/ibac/judge_test.go | 2 +- authbridge/authlib/plugins/ibac/plugin.go | 10 +- .../authlib/plugins/ibac/plugin_test.go | 4 +- .../plugins/inferenceparser/anthropic.go | 2 +- .../plugins/inferenceparser/anthropic_test.go | 2 +- .../authlib/plugins/inferenceparser/plugin.go | 6 +- .../plugins/inferenceparser/plugin_test.go | 2 +- .../plugins/inferenceparser/streaming_test.go | 2 +- .../jwtvalidation/e2e_audiences_test.go | 2 +- .../authlib/plugins/jwtvalidation/identity.go | 4 +- .../plugins/jwtvalidation/identity_test.go | 10 +- .../plugins/jwtvalidation/placeholder_test.go | 6 +- .../authlib/plugins/jwtvalidation/plugin.go | 26 +-- .../plugins/jwtvalidation/plugin_test.go | 28 +-- .../plugins/litellm_budgettrack/plugin.go | 4 +- .../authlib/plugins/mcpparser/plugin.go | 8 +- .../authlib/plugins/mcpparser/plugin_test.go | 2 +- .../plugins/mcpparser/streaming_test.go | 2 +- authbridge/authlib/plugins/opa/README.md | 14 +- authbridge/authlib/plugins/opa/plugin.go | 16 +- authbridge/authlib/plugins/opa/plugin_test.go | 8 +- authbridge/authlib/plugins/plugins_test.go | 20 +-- .../plugins/plugintesting/plugintesting.go | 6 +- authbridge/authlib/plugins/registry.go | 8 +- authbridge/authlib/plugins/registry_test.go | 6 +- authbridge/authlib/plugins/sparc/collect.go | 2 +- authbridge/authlib/plugins/sparc/plugin.go | 10 +- .../authlib/plugins/sparc/plugin_test.go | 2 +- authbridge/authlib/plugins/sparc/respond.go | 2 +- .../authlib/plugins/staticinject/plugin.go | 6 +- .../plugins/staticinject/plugin_test.go | 2 +- .../authlib/plugins/staticinject/resolver.go | 2 +- authbridge/authlib/plugins/stats.go | 4 +- .../authlib/plugins/tokenbroker/plugin.go | 8 +- .../plugins/tokenbroker/plugin_edge_test.go | 4 +- .../tokenbroker/plugin_request_test.go | 2 +- .../tokenbroker/plugin_routing_test.go | 2 +- .../plugins/tokenexchange/delegation_test.go | 4 +- .../plugins/tokenexchange/placeholder_test.go | 6 +- .../authlib/plugins/tokenexchange/plugin.go | 22 +-- .../plugins/tokenexchange/plugin_test.go | 8 +- .../authlib/plugins/tokenexchange/provider.go | 4 +- .../tokenexchange/provider_keycloak.go | 4 +- authbridge/authlib/reloader/reloader.go | 4 +- authbridge/authlib/reloader/reloader_test.go | 4 +- authbridge/authlib/session/intent_pin_test.go | 2 +- authbridge/authlib/session/store.go | 2 +- authbridge/authlib/session/store_test.go | 2 +- .../authlib/sessionapi/catalog_adapter.go | 4 +- authbridge/authlib/sessionapi/server.go | 8 +- authbridge/authlib/sessionapi/server_test.go | 4 +- authbridge/authlib/tls/client.go | 2 +- authbridge/authlib/tls/server.go | 2 +- authbridge/authlib/tls/server_test.go | 4 +- authbridge/cmd/README.md | 6 +- authbridge/cmd/abctl/README.md | 4 +- authbridge/cmd/abctl/apiclient/client.go | 4 +- authbridge/cmd/abctl/apiclient/client_test.go | 4 +- authbridge/cmd/abctl/apiclient/sse.go | 2 +- authbridge/cmd/abctl/edit/configmap.go | 4 +- authbridge/cmd/abctl/edit/configmap_test.go | 2 +- authbridge/cmd/abctl/edit/edit.go | 2 +- authbridge/cmd/abctl/edit/templates.go | 2 +- authbridge/cmd/abctl/edit/templates_test.go | 2 +- authbridge/cmd/abctl/edit/validate.go | 2 +- authbridge/cmd/abctl/edit/validate_test.go | 2 +- authbridge/cmd/abctl/go.mod | 6 +- authbridge/cmd/abctl/main.go | 6 +- authbridge/cmd/abctl/tui/app.go | 10 +- authbridge/cmd/abctl/tui/catalog_pane.go | 2 +- authbridge/cmd/abctl/tui/catalog_pane_test.go | 2 +- authbridge/cmd/abctl/tui/deps.go | 2 +- authbridge/cmd/abctl/tui/deps_test.go | 2 +- authbridge/cmd/abctl/tui/detail_pane.go | 4 +- authbridge/cmd/abctl/tui/detail_pane_test.go | 6 +- authbridge/cmd/abctl/tui/e2e_test.go | 8 +- authbridge/cmd/abctl/tui/edit_e2e_test.go | 2 +- authbridge/cmd/abctl/tui/edit_overlay.go | 2 +- authbridge/cmd/abctl/tui/events_pane.go | 2 +- authbridge/cmd/abctl/tui/events_pane_test.go | 2 +- authbridge/cmd/abctl/tui/keys.go | 4 +- authbridge/cmd/abctl/tui/namespaces_pane.go | 6 +- authbridge/cmd/abctl/tui/picker_test.go | 4 +- authbridge/cmd/abctl/tui/pipeline_pane.go | 2 +- .../cmd/abctl/tui/pipeline_pane_test.go | 2 +- .../cmd/abctl/tui/plugin_detail_pane.go | 2 +- .../cmd/abctl/tui/plugin_detail_pane_test.go | 2 +- authbridge/cmd/abctl/tui/pods_pane.go | 2 +- authbridge/cmd/abctl/tui/sessions_pane.go | 2 +- authbridge/cmd/authbridge-cpex/go.mod | 6 +- authbridge/cmd/authbridge-cpex/main.go | 48 ++--- authbridge/cmd/authbridge-envoy/Dockerfile | 2 +- authbridge/cmd/authbridge-envoy/go.mod | 8 +- authbridge/cmd/authbridge-envoy/go.sum | 4 +- authbridge/cmd/authbridge-envoy/main.go | 40 ++--- .../authbridge-envoy/plugins_contextguru.go | 2 +- .../cmd/authbridge-envoy/plugins_ibac.go | 2 +- authbridge/cmd/authbridge-proxy/Dockerfile | 2 +- authbridge/cmd/authbridge-proxy/go.mod | 8 +- authbridge/cmd/authbridge-proxy/go.sum | 4 +- authbridge/cmd/authbridge-proxy/main.go | 32 ++-- authbridge/cmd/authbridge-proxy/main_test.go | 6 +- .../cmd/authbridge-proxy/plugins_a2aparser.go | 2 +- .../authbridge-proxy/plugins_contextguru.go | 2 +- .../cmd/authbridge-proxy/plugins_ibac.go | 2 +- .../plugins_inferenceparser.go | 2 +- .../authbridge-proxy/plugins_jwtvalidation.go | 2 +- .../plugins_litellm_budgettrack.go | 2 +- .../cmd/authbridge-proxy/plugins_mcpparser.go | 2 +- .../cmd/authbridge-proxy/plugins_opa.go | 2 +- .../cmd/authbridge-proxy/plugins_sparc.go | 2 +- .../authbridge-proxy/plugins_staticinject.go | 2 +- .../authbridge-proxy/plugins_tokenbroker.go | 2 +- .../authbridge-proxy/plugins_tokenexchange.go | 2 +- authbridge/demos/README.md | 18 +- authbridge/demos/context-guru/README.md | 6 +- authbridge/demos/context-guru/k8s/agent.yaml | 6 +- authbridge/demos/context-guru/run.sh | 10 +- authbridge/demos/echo/Makefile | 56 +++--- authbridge/demos/echo/README.md | 20 +-- authbridge/demos/echo/agent/main.go | 16 +- authbridge/demos/echo/go.mod | 2 +- authbridge/demos/echo/k8s/agent.yaml | 30 ++-- authbridge/demos/echo/k8s/upstream.yaml | 2 +- .../demos/echo/scripts/patch-echo-config.sh | 2 +- .../demos/echo/scripts/setup_keycloak.py | 14 +- authbridge/demos/finance-sparc/Makefile | 20 +-- authbridge/demos/finance-sparc/README.md | 20 +-- .../demos/finance-sparc/finance-agent/main.go | 2 +- .../demos/finance-sparc/finance-mcp/main.go | 2 +- authbridge/demos/finance-sparc/go.mod | 2 +- authbridge/demos/finance-sparc/k8s/agent.yaml | 18 +- .../demos/finance-sparc/k8s/ollama.yaml | 2 +- .../demos/finance-sparc/k8s/sparc-patch.yaml | 2 +- .../demos/finance-sparc/scripts/drive-demo.sh | 2 +- .../demos/finance-sparc/scripts/host-setup.sh | 2 +- .../scripts/patch-sparc-config.sh | 4 +- .../scripts/setup_keycloak_finance.py | 6 +- .../scripts/stage-ollama-model.sh | 2 +- authbridge/demos/github-issue/aiac/Makefile | 2 +- .../demos/github-issue/aiac/aiac.env.TEMPLATE | 2 +- .../aiac/aiac_agent/utils/validators.py | 4 +- .../github-issue/aiac/scripts/show-result.py | 2 +- authbridge/demos/github-issue/demo-aiac.md | 52 +++--- authbridge/demos/github-issue/demo-manual.md | 108 ++++++------ authbridge/demos/github-issue/demo-rbac.md | 98 +++++------ authbridge/demos/github-issue/demo-ui.md | 156 ++++++++-------- authbridge/demos/github-issue/demo.md | 16 +- .../demos/github-issue/k8s/configmaps.yaml | 12 +- .../k8s/git-issue-agent-deployment.yaml | 28 +-- .../k8s/github-tool-deployment.yaml | 6 +- authbridge/demos/github-issue/rbac/Makefile | 20 +-- .../demos/github-issue/rbac/config.yaml | 4 +- .../demos/github-issue/rbac/policy.yaml | 6 +- .../demos/github-issue/setup_keycloak.py | 18 +- authbridge/demos/hr-cpex/Makefile | 6 +- authbridge/demos/hr-cpex/README.md | 14 +- authbridge/demos/hr-cpex/agent/Dockerfile | 2 +- .../demos/hr-cpex/k8s/00-namespace.yaml | 2 +- authbridge/demos/hr-cpex/k8s/20-hr-mcp.yaml | 2 +- authbridge/demos/ibac/Makefile | 38 ++-- authbridge/demos/ibac/README.md | 8 +- authbridge/demos/ibac/agent/main.go | 16 +- authbridge/demos/ibac/go.mod | 2 +- authbridge/demos/ibac/k8s/agent.yaml | 30 ++-- authbridge/demos/ibac/k8s/email-server.yaml | 2 +- .../demos/ibac/scripts/patch-ibac-config.sh | 2 +- authbridge/demos/mcp-parser/README.md | 14 +- authbridge/demos/mtls/Makefile | 8 +- authbridge/demos/mtls/README.md | 30 ++-- authbridge/demos/mtls/k8s/callee-envoy.yaml | 2 +- authbridge/demos/mtls/k8s/callee.yaml | 8 +- authbridge/demos/mtls/k8s/caller-envoy.yaml | 6 +- authbridge/demos/mtls/k8s/caller.yaml | 12 +- .../demos/mtls/k8s/envoy-config-mtls.yaml | 4 +- .../demos/mtls/scripts/patch-mtls-config.sh | 4 +- .../demos/weather-agent/demo-ui-advanced.md | 44 ++--- authbridge/demos/weather-agent/demo-ui.md | 106 +++++------ .../demos/weather-agent/demo-with-abctl.md | 24 +-- .../deploy_and_verify_advanced.sh | 20 +-- ...agentruntime-weather-service-advanced.yaml | 2 +- .../agentruntime-weather-tool-advanced.yaml | 6 +- .../k8s/configmaps-advanced.yaml | 18 +- .../k8s/weather-service-advanced.yaml | 10 +- .../k8s/weather-tool-advanced.yaml | 22 +-- .../setup_keycloak_weather_advanced.py | 4 +- authbridge/docs/framework-architecture.md | 6 +- authbridge/docs/idp-plugin-contract.md | 6 +- authbridge/docs/litellm-budgettrack-plugin.md | 4 +- authbridge/docs/plugin-reference.md | 4 +- authbridge/docs/plugin-tutorial.md | 10 +- authbridge/docs/sparc-plugin.md | 8 +- .../2026-05-22-authbridge-go-spiffe-sdk.md | 8 +- .../plans/2026-05-28-abctl-pipeline-edit.md | 26 +-- .../plans/2026-05-28-abctl-plugin-config.md | 2 +- .../plans/2026-05-28-abctl-pod-picker.md | 12 +- .../2026-06-02-credential-placeholder-swap.md | 30 ++-- .../2026-06-17-authbridge-tlsbridge-phase1.md | 6 +- ...6-05-22-authbridge-go-spiffe-sdk-design.md | 20 +-- .../2026-06-12-authbridge-tlsbridge-design.md | 2 +- authbridge/keycloak_sync.py | 2 +- authbridge/proxy-init/Makefile | 2 +- authbridge/proxy-init/README.md | 6 +- authbridge/sparc-service/Dockerfile | 2 +- authbridge/sparc-service/README.md | 6 +- authbridge/sparc-service/deploy/Makefile | 6 +- authbridge/sparc-service/deploy/README.md | 6 +- .../sparc-service/deploy/sparc-service.yaml | 6 +- authbridge/sparc-service/pyproject.toml | 6 +- .../sparc-service/sparc_service/__init__.py | 2 +- authbridge/sparc-service/sparc_service/api.py | 2 +- .../sparc-service/sparc_service/settings.py | 2 +- docs/README.md | 2 +- docs/proposals/authbridge-hooks.md | 2 +- local-build-and-test.sh | 46 ++--- tests/conftest.py | 2 +- verify-spire-keycloak.sh | 12 +- 326 files changed, 1583 insertions(+), 1583 deletions(-) diff --git a/.claude/skills/demo.md b/.claude/skills/demo.md index 0bbd2e191..5fac17144 100644 --- a/.claude/skills/demo.md +++ b/.claude/skills/demo.md @@ -4,9 +4,9 @@ This skill captures knowledge from building, debugging, and running AuthBridge d ## Repository Context -- **Repo:** `kagenti/kagenti-extensions` (monorepo) -- **Container registry:** `ghcr.io/kagenti/kagenti-extensions/` -- **Agent examples repo:** `kagenti/agent-examples` (separate repo, images NOT published to GHCR) +- **Repo:** `rossoctl/rossocortex` (monorepo) +- **Container registry:** `ghcr.io/rossoctl/rossocortex/` +- **Agent examples repo:** `rossoctl/examples` (separate repo, images NOT published to GHCR) - **Demo guides:** `authbridge/demos//demo-manual.md` (manual kubectl) and `demo-ui.md` (UI-driven) ## Demo Directory Convention @@ -27,20 +27,20 @@ demos// ## Building and Loading Images for Kind -Agent/tool images from `kagenti/agent-examples` must be built locally and loaded into Kind: +Agent/tool images from `rossoctl/examples` must be built locally and loaded into Kind: ```bash # Build from agent-examples repo -docker build -t ghcr.io/kagenti/agent-examples/:latest ./a2a// -docker build -t ghcr.io/kagenti/agent-examples/:latest ./mcp// +docker build -t ghcr.io/rossoctl/examples/:latest ./a2a// +docker build -t ghcr.io/rossoctl/examples/:latest ./mcp// # Build AuthBridge sidecar images -cd kagenti-extensions/authbridge/authproxy -docker build -f Dockerfile.init -t ghcr.io/kagenti/kagenti-extensions/proxy-init:latest . -docker build -f Dockerfile.envoy -t ghcr.io/kagenti/kagenti-extensions/envoy-with-processor:latest . +cd rossocortex/authbridge/authproxy +docker build -f Dockerfile.init -t ghcr.io/rossoctl/rossocortex/proxy-init:latest . +docker build -f Dockerfile.envoy -t ghcr.io/rossoctl/rossocortex/envoy-with-processor:latest . # Load into Kind -kind load docker-image --name kagenti +kind load docker-image --name rossoctl ``` Use fully qualified image names in Dockerfiles (e.g., `docker.io/library/golang:1.24.9-bookworm`) to avoid Podman/Buildah "short-name resolution enforced" errors in Shipwright builds. @@ -150,12 +150,12 @@ kubectl logs deployment/ -n -c envoy-proxy 2>&1 | grep "\[Token Exch ### Client Registration ```bash -kubectl logs deployment/ -n -c kagenti-client-registration +kubectl logs deployment/ -n -c rossoctl-client-registration # Query Keycloak (use --data-urlencode for SPIFFE IDs) curl -s -H "Authorization: Bearer $ADMIN_TOKEN" \ --data-urlencode "clientId=spiffe://localtest.me/ns//sa/" \ - --get "http://keycloak.localtest.me:8080/admin/realms/kagenti/clients" | jq '.[0].clientId' + --get "http://keycloak.localtest.me:8080/admin/realms/rossoctl/clients" | jq '.[0].clientId' ``` ## Demo Deployment Checklist diff --git a/.claude/skills/orchestrate/SKILL.md b/.claude/skills/orchestrate/SKILL.md index 747963871..c693f6661 100644 --- a/.claude/skills/orchestrate/SKILL.md +++ b/.claude/skills/orchestrate/SKILL.md @@ -63,15 +63,15 @@ What was provided? ### Route logic -1. **`/orchestrate `** -- If the path points to a git repository, derive the target name from the directory basename. Check `/tmp/kagenti/orchestrate//` for existing state. If no scan report exists, invoke `orchestrate:scan`. If scan exists but no plan, invoke `orchestrate:plan`. If both exist, determine the next incomplete phase and invoke it. +1. **`/orchestrate `** -- If the path points to a git repository, derive the target name from the directory basename. Check `/tmp/rossoctl/orchestrate//` for existing state. If no scan report exists, invoke `orchestrate:scan`. If scan exists but no plan, invoke `orchestrate:plan`. If both exist, determine the next incomplete phase and invoke it. 2. **`/orchestrate `** -- Validate that `scan-report.md` and `plan.md` exist for the current target. If missing, instruct the user to run `/orchestrate ` first. Otherwise invoke the requested phase skill directly (e.g., `orchestrate:precommit`). -3. **`/orchestrate status`** -- List all directories under `/tmp/kagenti/orchestrate/`, read each target's `phase-status.md`, and display a summary table showing target name, current phase, and completion percentage. +3. **`/orchestrate status`** -- List all directories under `/tmp/rossoctl/orchestrate/`, read each target's `phase-status.md`, and display a summary table showing target name, current phase, and completion percentage. ## Phase Status Tracking -All orchestration state is persisted under `/tmp/kagenti/orchestrate//`: +All orchestration state is persisted under `/tmp/rossoctl/orchestrate//`: | File | Purpose | |------|---------| @@ -154,5 +154,5 @@ git clone git@github.com:org/repo.git .repos/repo-name | Skill | Description | |-------|-------------| -| `onboard:link` | Link a newly-orchestrated repo to Kagenti | +| `onboard:link` | Link a newly-orchestrated repo to Rossoctl | | `onboard:standards` | Apply organizational standards and conventions | diff --git a/.claude/skills/orchestrate:ci/SKILL.md b/.claude/skills/orchestrate:ci/SKILL.md index 1d9fd05be..e4af15073 100644 --- a/.claude/skills/orchestrate:ci/SKILL.md +++ b/.claude/skills/orchestrate:ci/SKILL.md @@ -29,7 +29,7 @@ flowchart TD # Orchestrate: CI Add comprehensive CI workflows to a target repository. This is Phase 4 and -produces PR #3. Encodes the kagenti/kagenti gold standard: lint, test, build, +produces PR #3. Encodes the rossoctl/rossoctl gold standard: lint, test, build, security scanning, dependency management, and supply chain hardening. ## When to Use @@ -39,8 +39,8 @@ security scanning, dependency management, and supply chain hardening. ## Prerequisites -- Plan exists at `/tmp/kagenti/orchestrate//plan.md` -- Scan report at `/tmp/kagenti/orchestrate//scan-report.md` +- Plan exists at `/tmp/rossoctl/orchestrate//plan.md` +- Scan report at `/tmp/rossoctl/orchestrate//scan-report.md` - Target repo in `.repos//` ## Read Scan Report First @@ -283,7 +283,7 @@ Use `docker/build-push-action` with: **Include when:** Repo is actively maintained (has recent commits). -Use the kagenti org reusable workflow: +Use the rossoctl org reusable workflow: ```yaml name: Close Stale Issues and PRs @@ -294,7 +294,7 @@ on: jobs: stale: - uses: kagenti/.github/.github/workflows/stale.yaml@main + uses: rossoctl/.github/.github/workflows/stale.yaml@main ``` ### 2.3 PR Title Verification @@ -341,7 +341,7 @@ Pair with comment-triggered E2E: ## Action Version Reference When generating workflows, use the latest SHA-pinned versions. Look up current -SHAs from the kagenti/kagenti main repo's workflows as the reference. All +SHAs from the rossoctl/rossoctl main repo's workflows as the reference. All actions MUST be SHA-pinned with a version comment: ```yaml @@ -399,7 +399,7 @@ gh pr create --repo org/repo --title "Add comprehensive CI workflows" --body "Ph ## Update Phase Status -Set ci to `complete` in `/tmp/kagenti/orchestrate//phase-status.md`. +Set ci to `complete` in `/tmp/rossoctl/orchestrate//phase-status.md`. ## Related Skills diff --git a/.claude/skills/orchestrate:plan/SKILL.md b/.claude/skills/orchestrate:plan/SKILL.md index 75727b4bf..07241e7fd 100644 --- a/.claude/skills/orchestrate:plan/SKILL.md +++ b/.claude/skills/orchestrate:plan/SKILL.md @@ -33,7 +33,7 @@ is Phase 1 — interactive brainstorming with the developer, no PRs. Scan report must exist: ```bash -cat /tmp/kagenti/orchestrate//scan-report.md +cat /tmp/rossoctl/orchestrate//scan-report.md ``` ## Planning Process @@ -78,7 +78,7 @@ Target 600-700 lines per PR. For each phase: ## Plan Output -Save to `/tmp/kagenti/orchestrate//plan.md`: +Save to `/tmp/rossoctl/orchestrate//plan.md`: ```markdown # Enhancement Plan: @@ -128,7 +128,7 @@ Save to `/tmp/kagenti/orchestrate//plan.md`: Initialize phase tracking: ```bash -cat > /tmp/kagenti/orchestrate//phase-status.md << 'EOF' +cat > /tmp/rossoctl/orchestrate//phase-status.md << 'EOF' # Phase Status: | Phase | Status | PR | Date | diff --git a/.claude/skills/orchestrate:precommit/SKILL.md b/.claude/skills/orchestrate:precommit/SKILL.md index cddfd92ea..5aafca154 100644 --- a/.claude/skills/orchestrate:precommit/SKILL.md +++ b/.claude/skills/orchestrate:precommit/SKILL.md @@ -35,7 +35,7 @@ produces PR #1 — the foundation that validates all subsequent PRs. ## Prerequisites -- Plan exists at `/tmp/kagenti/orchestrate//plan.md` +- Plan exists at `/tmp/rossoctl/orchestrate//plan.md` - Target repo cloned in `.repos//` ## Step 1: Detect Language @@ -212,7 +212,7 @@ gh pr create --repo org/repo --title "Add pre-commit hooks and code quality base ## Update Phase Status -Update `/tmp/kagenti/orchestrate//phase-status.md`: +Update `/tmp/rossoctl/orchestrate//phase-status.md`: - Set precommit to `complete` - Record PR number and date diff --git a/.claude/skills/orchestrate:replicate/SKILL.md b/.claude/skills/orchestrate:replicate/SKILL.md index 26dc28798..d89b22900 100644 --- a/.claude/skills/orchestrate:replicate/SKILL.md +++ b/.claude/skills/orchestrate:replicate/SKILL.md @@ -54,7 +54,7 @@ making it fully self-sufficient. This is Phase 6. After copying, adapt the skills: -1. **Remove source-specific references** — strip kagenti-specific paths or +1. **Remove source-specific references** — strip rossoctl-specific paths or assumptions that don't apply 2. **Verify frontmatter** — every `name:` field must match its directory name 3. **Update Related Skills** — only reference skills that exist in the copied set diff --git a/.claude/skills/orchestrate:review/SKILL.md b/.claude/skills/orchestrate:review/SKILL.md index 379ccd76a..5018b6707 100644 --- a/.claude/skills/orchestrate:review/SKILL.md +++ b/.claude/skills/orchestrate:review/SKILL.md @@ -37,7 +37,7 @@ submits reviews after user approval. ## Prerequisites -- `scan-report.md` and `plan.md` exist in `/tmp/kagenti/orchestrate//` +- `scan-report.md` and `plan.md` exist in `/tmp/rossoctl/orchestrate//` - Phases 2-6 are complete (or at least the phases that were planned) - PRs are open on the target repo @@ -210,7 +210,7 @@ Update `phase-status.md` when complete: ```bash # Update phase-status.md -sed -i '' 's/| review .*/| review | complete | -- | YYYY-MM-DD |/' /tmp/kagenti/orchestrate//phase-status.md +sed -i '' 's/| review .*/| review | complete | -- | YYYY-MM-DD |/' /tmp/rossoctl/orchestrate//phase-status.md ``` ## Related Skills diff --git a/.claude/skills/orchestrate:scan/SKILL.md b/.claude/skills/orchestrate:scan/SKILL.md index 10ecd9fde..a5b84a27a 100644 --- a/.claude/skills/orchestrate:scan/SKILL.md +++ b/.claude/skills/orchestrate:scan/SKILL.md @@ -277,7 +277,7 @@ Then follow the `cve:scan` skill workflow: Advisory Database 4. **Classify** — confirmed / suspected / false positive -Write CVE findings to `/tmp/kagenti/cve//scan-report.json` (never to +Write CVE findings to `/tmp/rossoctl/cve//scan-report.json` (never to git-tracked files). Include a summary in the scan report. Key areas to focus on: @@ -326,10 +326,10 @@ git -C .repos/ remote -v ## Output Format -Save scan report to `/tmp/kagenti/orchestrate//scan-report.md`: +Save scan report to `/tmp/rossoctl/orchestrate//scan-report.md`: ```bash -mkdir -p /tmp/kagenti/orchestrate/ +mkdir -p /tmp/rossoctl/orchestrate/ ``` Report template: @@ -439,7 +439,7 @@ Report template: ## Dependency Vulnerabilities (cve:scan) - Scan method: [Trivy + LLM + WebSearch / LLM + WebSearch / LLM only] -- Full report: `/tmp/kagenti/cve//scan-report.json` +- Full report: `/tmp/rossoctl/cve//scan-report.json` | Severity | Count | |----------|-------| @@ -458,7 +458,7 @@ Report template: |---------|----------|---------| | [e.g., insecure port, no input validation] | HIGH/MEDIUM | [brief description] | -> **Note:** CVE IDs and detailed descriptions are in `/tmp/kagenti/cve//scan-report.json` only. +> **Note:** CVE IDs and detailed descriptions are in `/tmp/rossoctl/cve//scan-report.json` only. > Do NOT copy CVE IDs into git-tracked files, PRs, or issues. ## Gap Summary diff --git a/.claude/skills/orchestrate:security/SKILL.md b/.claude/skills/orchestrate:security/SKILL.md index 2f687ab37..c2def4566 100644 --- a/.claude/skills/orchestrate:security/SKILL.md +++ b/.claude/skills/orchestrate:security/SKILL.md @@ -132,7 +132,7 @@ All commits must be signed off (`git commit -s`). ## Step 4: LICENSE Check if LICENSE exists. If missing: -- Check the org's standard license (most kagenti repos use Apache 2.0) +- Check the org's standard license (most rossoctl repos use Apache 2.0) - Add the appropriate LICENSE file - If unsure, flag in the PR for maintainer decision diff --git a/.claude/skills/skills:validate/SKILL.md b/.claude/skills/skills:validate/SKILL.md index 5ade71b23..c5861d958 100644 --- a/.claude/skills/skills:validate/SKILL.md +++ b/.claude/skills/skills:validate/SKILL.md @@ -51,7 +51,7 @@ Skills operate on either **sandbox** (safe) or **management** (requires approval | **Management** | Management cluster, AWS resources, git push, destructive ops | NO | Can chain commands (user approves anyway) | ### Sandbox skills (auto-approved) -Commands target `localtest.me`, `KUBECONFIG=~/clusters/hcp/kagenti-hypershift-custom-*`, or Kind clusters. +Commands target `localtest.me`, `KUBECONFIG=~/clusters/hcp/rossoctl-hypershift-custom-*`, or Kind clusters. **IMPORTANT**: Run each command separately — not chained with `&&`. Chained or multiline commands break Claude Code's auto-approve pattern matching. @@ -60,18 +60,18 @@ Commands target `localtest.me`, `KUBECONFIG=~/clusters/hcp/kagenti-hypershift-cu Check pod status: ```bash -kubectl get pods -n kagenti-system +kubectl get pods -n rossoctl-system ``` Check logs: ```bash -kubectl logs -n kagenti-system deployment/mlflow +kubectl logs -n rossoctl-system deployment/mlflow ``` ## BAD (chained commands won't match auto-approve patterns) ```bash -kubectl get pods -n kagenti-system && kubectl logs -n kagenti-system deployment/mlflow +kubectl get pods -n rossoctl-system && kubectl logs -n rossoctl-system deployment/mlflow ``` ``` @@ -132,7 +132,7 @@ For each command in a sandbox skill, verify it matches a pattern in `.claude/set | `kubectl describe` | `Bash(kubectl describe:*)` | | `kubectl logs` | `Bash(kubectl logs:*)` | | `helm list` | `Bash(helm list:*)` | -| `KUBECONFIG=~/clusters/hcp/... kubectl` | `Bash(KUBECONFIG=*/clusters/hcp/kagenti-hypershift-custom-*/auth/kubeconfig kubectl:*)` | +| `KUBECONFIG=~/clusters/hcp/... kubectl` | `Bash(KUBECONFIG=*/clusters/hcp/rossoctl-hypershift-custom-*/auth/kubeconfig kubectl:*)` | | `uv run pytest` | `Bash(uv run pytest:*)` | If a command is NOT covered, add the pattern to `.claude/settings.json` in the `allow` array. @@ -142,7 +142,7 @@ If a command is NOT covered, add the pattern to `.claude/settings.json` in the ` When validating multiple skills: ``` -TaskCreate: "kagenti | skills | | Verify | Validate " +TaskCreate: "rossoctl | skills | | Verify | Validate " ``` ## Related Skills diff --git a/.claude/skills/skills:write/SKILL.md b/.claude/skills/skills:write/SKILL.md index fe07a2c0f..f6310238e 100644 --- a/.claude/skills/skills:write/SKILL.md +++ b/.claude/skills/skills:write/SKILL.md @@ -100,12 +100,12 @@ Claude Code auto-approves commands by matching the first token against `.claude/ ```markdown Check pod status: ```bash -kubectl get pods -n kagenti-system +kubectl get pods -n rossoctl-system ``` Check logs: ```bash -kubectl logs -n kagenti-system deployment/mlflow +kubectl logs -n rossoctl-system deployment/mlflow ``` ``` @@ -115,7 +115,7 @@ For HyperShift, prefix each command individually: ```markdown ```bash -KUBECONFIG=~/clusters/hcp/kagenti-hypershift-custom-$CLUSTER/auth/kubeconfig kubectl get pods -n kagenti-system +KUBECONFIG=~/clusters/hcp/rossoctl-hypershift-custom-$CLUSTER/auth/kubeconfig kubectl get pods -n rossoctl-system ``` ``` @@ -125,10 +125,10 @@ Commands targeting management clusters or AWS need user approval anyway, so mult ### Temporary Files -Skills that download logs, artifacts, or save analysis output should use `/tmp/kagenti//` as the working directory: +Skills that download logs, artifacts, or save analysis output should use `/tmp/rossoctl//` as the working directory: ```bash -mkdir -p /tmp/kagenti/rca +mkdir -p /tmp/rossoctl/rca ``` This path is auto-approved for read/write in `.claude/settings.json`. @@ -184,7 +184,7 @@ Every workflow skill (tdd, rca, ci, etc.) MUST include a Task Tracking section. | | | | | ``` -- **worktree**: git worktree name (e.g., `mlflow-ci`) or `kagenti` for main repo +- **worktree**: git worktree name (e.g., `mlflow-ci`) or `rossoctl` for main repo - **PR**: PR reference (e.g., `PR#569`) or `none` - **plan-doc**: plan filename (e.g., `calm-toast.md`) or `ad-hoc` if no plan - **topic**: area of work (e.g., `Kind CI`, `MLflow init`, `CodeQL`) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0dcca4104..738c516cf 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,12 +1,12 @@ # Default owners for everything -* @kagenti/maintainers +* @rossoctl/maintainers # AuthBridge components -authbridge/ @kagenti/maintainers +authbridge/ @rossoctl/maintainers # CI/CD and GitHub configuration -.github/ @kagenti/platform +.github/ @rossoctl/platform # Documentation -*.md @kagenti/maintainers -docs/ @kagenti/maintainers +*.md @rossoctl/maintainers +docs/ @rossoctl/maintainers diff --git a/.github/codeql/codeql-config.yml b/.github/codeql/codeql-config.yml index b8d8a7c1e..dab6f214b 100644 --- a/.github/codeql/codeql-config.yml +++ b/.github/codeql/codeql-config.yml @@ -1,4 +1,4 @@ -name: kagenti-extensions CodeQL config +name: rossocortex CodeQL config queries: - uses: security-extended diff --git a/.github/spellcheck/.wordlist.txt b/.github/spellcheck/.wordlist.txt index d36b38d98..7e57e9a53 100644 --- a/.github/spellcheck/.wordlist.txt +++ b/.github/spellcheck/.wordlist.txt @@ -54,8 +54,8 @@ JWT JWT's JWTs Kagent -Kagenti -Kagenti's +Rossoctl +Rossoctl's Keycloak Keycloak's Kubebuilder @@ -276,7 +276,7 @@ jsonnet jsonpath jwks k8s -kagenti +rossoctl keycloak ko kube diff --git a/.github/workflows/pr-verifier.yml b/.github/workflows/pr-verifier.yml index 22c9e8237..b2cdfdbd8 100644 --- a/.github/workflows/pr-verifier.yml +++ b/.github/workflows/pr-verifier.yml @@ -10,4 +10,4 @@ jobs: verify-pr-title: permissions: pull-requests: read - uses: kagenti/.github/.github/workflows/pr-verifier-required.yml@5df2608afc813a6ec4a002a9ea05640863549122 # main, 2026-06-25 + uses: rossoctl/.github/.github/workflows/pr-verifier-required.yml@5df2608afc813a6ec4a002a9ea05640863549122 # main, 2026-06-25 diff --git a/.github/workflows/project.yml b/.github/workflows/project.yml index e4e41d734..38ff202a2 100644 --- a/.github/workflows/project.yml +++ b/.github/workflows/project.yml @@ -1,4 +1,4 @@ -name: Kagenti Project Automation +name: Rossoctl Project Automation on: issues: @@ -11,7 +11,7 @@ permissions: jobs: add: - name: Add item to Kagenti Project + name: Add item to Rossoctl Project permissions: issues: write @@ -19,5 +19,5 @@ jobs: contents: read # Pinned to @main intentionally: org-internal workflows propagate updates automatically. - uses: kagenti/.github/.github/workflows/add-to-project.yml@main + uses: rossoctl/.github/.github/workflows/add-to-project.yml@main secrets: inherit diff --git a/.github/workflows/self-assign.yml b/.github/workflows/self-assign.yml index a4130cf50..1b55966a0 100644 --- a/.github/workflows/self-assign.yml +++ b/.github/workflows/self-assign.yml @@ -1,9 +1,9 @@ # Issue Self-Assign # # Thin caller for the org-wide reusable self-assign workflow. -# Configuration and defaults are managed centrally in kagenti/.github. +# Configuration and defaults are managed centrally in rossoctl/.github. # -# Reference: https://github.com/kagenti/.github/blob/main/.github/workflows/self-assign-reusable.yml +# Reference: https://github.com/rossoctl/.github/blob/main/.github/workflows/self-assign-reusable.yml # name: Issue self-assign @@ -17,6 +17,6 @@ permissions: jobs: self-assign: - uses: kagenti/.github/.github/workflows/self-assign-reusable.yml@main + uses: rossoctl/.github/.github/workflows/self-assign-reusable.yml@main secrets: ISSUE_ASSIGN_TOKEN: ${{ secrets.ISSUE_ASSIGN_TOKEN }} diff --git a/.github/workflows/stale.yaml b/.github/workflows/stale.yaml index b317f8cd7..9d4138903 100644 --- a/.github/workflows/stale.yaml +++ b/.github/workflows/stale.yaml @@ -1,9 +1,9 @@ # Stale Issue and PR Management # # Thin caller for the org-wide reusable stale workflow. -# Configuration and defaults are managed centrally in kagenti/.github. +# Configuration and defaults are managed centrally in rossoctl/.github. # -# Reference: https://github.com/kagenti/.github/blob/main/.github/workflows/stale.yaml +# Reference: https://github.com/rossoctl/.github/blob/main/.github/workflows/stale.yaml # name: Close Stale Issues and PRs @@ -18,4 +18,4 @@ permissions: jobs: stale: - uses: kagenti/.github/.github/workflows/stale.yaml@main + uses: rossoctl/.github/.github/workflows/stale.yaml@main diff --git a/.gitignore b/.gitignore index 599ffe1e7..071acdecb 100644 --- a/.gitignore +++ b/.gitignore @@ -69,7 +69,7 @@ __pycache__/ .pytest_cache/ .mypy_cache/ test-jwt-rotation.sh -kagenti-webhook/bin/ +rossoctl-webhook/bin/ # Go build artifacts — local `go build` outputs in cmd/* dirs # (binary name matches the package dir; trivially `git add`-ed by mistake). diff --git a/CLAUDE.md b/CLAUDE.md index a8959520d..20fb3b879 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,6 +1,6 @@ -# CLAUDE.md - Kagenti Extensions +# CLAUDE.md - Rossoctl Extensions -This file provides context for Claude (AI assistant) when working with the `kagenti-extensions` monorepo. +This file provides context for Claude (AI assistant) when working with the `rossocortex` monorepo. ## AI Assistant Instructions @@ -8,18 +8,18 @@ This file provides context for Claude (AI assistant) when working with the `kage ## Repository Overview -**kagenti-extensions** contains Kubernetes security extensions for the [Kagenti](https://github.com/kagenti/kagenti) ecosystem. It provides **zero-trust authentication** for Kubernetes workloads through transparent token exchange and dynamic Keycloak client registration using SPIFFE/SPIRE identities. +**rossocortex** contains Kubernetes security extensions for the [Rossoctl](https://github.com/rossoctl/rossoctl) ecosystem. It provides **zero-trust authentication** for Kubernetes workloads through transparent token exchange and dynamic Keycloak client registration using SPIFFE/SPIRE identities. -The sidecar injection webhook lives in a separate repo: [kagenti/kagenti-operator](https://github.com/kagenti/kagenti-operator). +The sidecar injection webhook lives in a separate repo: [rossoctl/operator](https://github.com/rossoctl/operator). -**GitHub:** `github.com/kagenti/kagenti-extensions` -**Container registry:** `ghcr.io/kagenti/kagenti-extensions/` +**GitHub:** `github.com/rossoctl/rossocortex` +**Container registry:** `ghcr.io/rossoctl/rossocortex/` **License:** Apache 2.0 ## Top-Level Directory Structure ``` -kagenti-extensions/ +rossocortex/ ├── authbridge/ # Authentication bridge components │ ├── authlib/ # Shared auth building blocks (Go module) │ │ ├── validation/ # JWKS-backed JWT verifier @@ -82,7 +82,7 @@ kagenti-extensions/ ### 2. Client Registration Keycloak client registration for workloads is handled by the -**kagenti-operator** (separate repo) — see `kagenti-operator/docs/operator-managed-client-registration.md`. +**operator** (separate repo) — see `operator/docs/operator-managed-client-registration.md`. The operator creates a Secret with `client-id.txt` + `client-secret.txt` and the webhook mounts it at `/shared/` in the workload pod. The in-pod `client-registration` sidecar that previously lived in this @@ -90,7 +90,7 @@ repo has been removed. ## How the Components Work Together -The kagenti-operator (in a separate repo) injects AuthBridge sidecars +The operator (in a separate repo) injects AuthBridge sidecars into workload pods. Default deployment shape (proxy-sidecar mode): ``` @@ -163,7 +163,7 @@ lowercase prefixes. Use `Fix:` / `Feat:` / `Docs:` in PR titles. ## Container Images -All images are pushed to `ghcr.io/kagenti/kagenti-extensions/` from +All images are pushed to `ghcr.io/rossoctl/rossocortex/` from `.github/workflows/build.yaml`: | Image | Source | Description | @@ -212,7 +212,7 @@ Hooks: | Service | Required | Purpose | |---------|----------|---------| | Kubernetes | Yes | Target platform (v1.25+ recommended) | -| [kagenti-operator](https://github.com/kagenti/kagenti-operator) | Yes | Injects AuthBridge sidecars into workload pods | +| [operator](https://github.com/rossoctl/operator) | Yes | Injects AuthBridge sidecars into workload pods | | Keycloak | Yes | OAuth2/OIDC provider, token exchange | | SPIRE | Optional | SPIFFE identity (JWT-SVIDs) for workloads | @@ -235,12 +235,12 @@ When the operator injects sidecars, the target namespace needs these resources: ### Building Everything Locally The repo-root `local-build-and-test.sh` orchestrates every image -the platform needs (`spiffe-idp-setup` from kagenti, plus +the platform needs (`spiffe-idp-setup` from rossoctl, plus `authbridge`, `authbridge-envoy`, `authbridge-lite`, `proxy-init` from this repo) and loads them into a Kind cluster: ```bash -KAGENTI_DIR=../kagenti ./local-build-and-test.sh +ROSSOCTL_DIR=../rossoctl ./local-build-and-test.sh ``` To build a single image directly: @@ -260,8 +260,8 @@ cd authbridge && podman build -f cmd/authbridge-proxy/Dockerfile \ ### Running the Full Demo -1. Set up a Kind cluster with SPIRE + Keycloak (use [Kagenti Ansible installer](https://github.com/kagenti/kagenti/blob/main/docs/install.md)) -2. Deploy the webhook via [kagenti-operator](https://github.com/kagenti/kagenti-operator) +1. Set up a Kind cluster with SPIRE + Keycloak (use [Rossoctl Ansible installer](https://github.com/rossoctl/rossoctl/blob/main/docs/install.md)) +2. Deploy the webhook via [operator](https://github.com/rossoctl/operator) 3. See the [AuthBridge demos index](authbridge/demos/README.md) for a recommended learning path: - **Getting started**: `authbridge/demos/weather-agent/demo-ui.md` (inbound validation, UI deployment) - **Full flow**: `authbridge/demos/github-issue/demo-ui.md` (token exchange + scope-based access) @@ -271,7 +271,7 @@ cd authbridge && podman build -f cmd/authbridge-proxy/Dockerfile \ 1. Add entry to `.github/workflows/build.yaml` matrix (`image_config` array) 2. Provide `name`, `context`, and `dockerfile` fields -3. Image will be pushed to `ghcr.io/kagenti/kagenti-extensions/` +3. Image will be pushed to `ghcr.io/rossoctl/rossocortex/` ## Code Style and Conventions diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a3337b2a6..c0b46648a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ -# Contributing to Kagenti Extensions +# Contributing to Rossoctl Extensions -Greetings! We are grateful for your interest in joining the Kagenti community and making a positive impact. Whether you're raising issues, enhancing documentation, fixing bugs, or developing new features, your contributions are essential to our success. +Greetings! We are grateful for your interest in joining the Rossoctl community and making a positive impact. Whether you're raising issues, enhancing documentation, fixing bugs, or developing new features, your contributions are essential to our success. To get started, kindly read through this document and familiarize yourself with our code of conduct. @@ -8,7 +8,7 @@ We can't wait to collaborate with you! ## Contributing Code -Please follow the [Contribution guide](https://github.com/kagenti/kagenti/blob/main/CONTRIBUTING.md#contributing-to-this-project) as found in the Kagenti Repository for instructions on how to contribute to our repositories. +Please follow the [Contribution guide](https://github.com/rossoctl/rossoctl/blob/main/CONTRIBUTING.md#contributing-to-this-project) as found in the Rossoctl Repository for instructions on how to contribute to our repositories. ## Claiming an Issue @@ -25,8 +25,8 @@ Comment `/claim` on an issue to have it automatically assigned to you. Issues la ```bash # Clone the repository -git clone https://github.com/kagenti/kagenti-extensions.git -cd kagenti-extensions +git clone https://github.com/rossoctl/rossocortex.git +cd rossocortex # Install pre-commit hooks pre-commit install @@ -83,7 +83,7 @@ Smaller pull requests are typically easier to review and merge. If your pull req ## Licensing -Kagenti Extensions is [Apache 2.0 licensed](LICENSE) and we accept contributions via +Rossoctl Extensions is [Apache 2.0 licensed](LICENSE) and we accept contributions via GitHub pull requests. ## Certificate of Origin diff --git a/LOCAL_TESTING_GUIDE.md b/LOCAL_TESTING_GUIDE.md index d92f7980d..63a1def5d 100644 --- a/LOCAL_TESTING_GUIDE.md +++ b/LOCAL_TESTING_GUIDE.md @@ -1,6 +1,6 @@ # Local Testing Guide for JWT-SVID Authentication -> **⚠️ This guide is stale after kagenti-extensions#411.** It was written +> **⚠️ This guide is stale after rossocortex#411.** It was written > for the pre-#411 multi-sidecar shape (separate `client-registration`, > `envoy-with-processor`, and standalone `spiffe-helper` containers) and > several of its YAML examples reference images that no longer publish. @@ -23,10 +23,10 @@ This guide walks you through testing JWT-SVID authentication using local images ## ⚠️ Important: Use the Build Script -**CRITICAL**: You MUST run the `./local-build-and-test.sh` script to build all required images. Do NOT build images individually with `docker build` or `podman build` commands, as this will miss critical images like `spiffe-idp-setup:local` (located in the kagenti repo). +**CRITICAL**: You MUST run the `./local-build-and-test.sh` script to build all required images. Do NOT build images individually with `docker build` or `podman build` commands, as this will miss critical images like `spiffe-idp-setup:local` (located in the rossoctl repo). The script: -- Builds images from **both** kagenti and kagenti-extensions repositories +- Builds images from **both** rossoctl and rossocortex repositories - Automatically detects Docker vs Podman - Loads all images into your Kind cluster - Ensures consistent image tags and pull policies @@ -35,15 +35,15 @@ The script: - Docker or Podman running - Kind CLI installed -- Both `kagenti` and `kagenti-extensions` repositories cloned +- Both `rossoctl` and `rossocortex` repositories cloned ## Step 0: Create Kind Cluster -The Kagenti ansible installer can create a Kind cluster automatically, but for local image testing, it's better to create it manually first: +The Rossoctl ansible installer can create a Kind cluster automatically, but for local image testing, it's better to create it manually first: ```bash # Create a Kind cluster with the correct name -kind create cluster --name kagenti-dev --config - < ``` -2. For webhook changes, see [kagenti-operator](https://github.com/kagenti/kagenti-operator) for redeployment instructions. +2. For webhook changes, see [operator](https://github.com/rossoctl/operator) for redeployment instructions. 3. Verify new images are loaded: ```bash - kind get images --name kagenti-dev | grep :local + kind get images --name rossoctl-dev | grep :local ``` ## Verify Federated-JWT Configuration @@ -763,7 +763,7 @@ kubectl get configmap authbridge-config -n -o jsonpath='{.data.CLIEN # 2. Deploy an agent and check client-registration logs # (After deploying an agent in Step 4) -kubectl logs -n deployment/ -c kagenti-client-registration -f +kubectl logs -n deployment/ -c rossoctl-client-registration -f # Expected: "Configuring client for JWT-SVID authentication (federated-jwt)" # 3. Verify Keycloak client uses federated-jwt authenticator @@ -772,7 +772,7 @@ kubectl run test-curl --rm -i --image=curlimages/curl --restart=Never -- sh -c " ADMIN_TOKEN=\$(curl -s 'http://keycloak-service.keycloak.svc:8080/realms/master/protocol/openid-connect/token' \ -d 'grant_type=password' -d 'client_id=admin-cli' -d 'username=admin' -d 'password=admin' | jq -r '.access_token') curl -s -H 'Authorization: Bearer \$ADMIN_TOKEN' \ - 'http://keycloak-service.keycloak.svc:8080/admin/realms/kagenti/clients' | \ + 'http://keycloak-service.keycloak.svc:8080/admin/realms/rossoctl/clients' | \ jq '.[] | select(.clientId | contains(\"spiffe\")) | {clientId, clientAuthenticatorType}' " # Expected: "clientAuthenticatorType": "federated-jwt" diff --git a/Makefile b/Makefile index c33a06cbf..b336fc2b4 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# Root Makefile for kagenti-extensions monorepo +# Root Makefile for rossocortex monorepo # Orchestrates linting and formatting across all sub-projects .PHONY: lint fmt pre-commit build-proxy-init help diff --git a/README.md b/README.md index 82aeb3f9e..146a95f41 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# Kagenti Extensions +# Rossoctl Extensions -Kubernetes security extensions for the [Kagenti](https://github.com/kagenti/kagenti) ecosystem, providing **zero-trust authentication** for workloads through transparent token exchange and dynamic Keycloak client registration using SPIFFE/SPIRE identities. +Kubernetes security extensions for the [Rossoctl](https://github.com/rossoctl/rossoctl) ecosystem, providing **zero-trust authentication** for workloads through transparent token exchange and dynamic Keycloak client registration using SPIFFE/SPIRE identities. ## AuthBridge @@ -14,14 +14,14 @@ Kubernetes security extensions for the [Kagenti](https://github.com/kagenti/kage - **[proxy-init](./authbridge/proxy-init/)** — iptables init container used by envoy-sidecar mode for transparent traffic interception. - **[Keycloak Sync](./authbridge/keycloak_sync.py)** — Declarative tool for synchronizing Keycloak configuration. -Keycloak client registration runs in the [kagenti-operator](https://github.com/kagenti/kagenti-operator) (separate repo, post-#411 / kagenti-operator#361 — no in-pod registration sidecar). +Keycloak client registration runs in the [operator](https://github.com/rossoctl/operator) (separate repo, post-#411 / operator#361 — no in-pod registration sidecar). See the [AuthBridge README](./authbridge/README.md) for architecture details and the [demos index](./authbridge/demos/README.md) for getting started. ## Container Images -All images are published to `ghcr.io/kagenti/kagenti-extensions/`. After -kagenti-extensions#411 the unified binary was split into three +All images are published to `ghcr.io/rossoctl/rossocortex/`. After +rossocortex#411 the unified binary was split into three mode-specific combined images, and the per-component sidecars (`client-registration`, standalone `spiffe-helper`) were retired: @@ -34,7 +34,7 @@ mode-specific combined images, and the per-component sidecars `spiffe-helper` is bundled inside each combined image and gated per workload by the `SPIRE_ENABLED` env var. Client registration is -handled by the kagenti-operator's `ClientRegistrationReconciler` and +handled by the operator's `ClientRegistrationReconciler` and no longer ships as a separate image. The legacy `authbridge-unified`, `authbridge-light`, `client-registration`, and standalone `spiffe-helper` images are no longer published; older release tags continue to @@ -60,8 +60,8 @@ See [LOCAL_TESTING_GUIDE.md](./LOCAL_TESTING_GUIDE.md) for the full local develo ## Related Repositories -- [kagenti](https://github.com/kagenti/kagenti) — Core Kagenti platform -- [kagenti-operator](https://github.com/kagenti/kagenti-operator) — Kubernetes operator for sidecar injection (includes the admission webhook) +- [rossoctl](https://github.com/rossoctl/rossoctl) — Core Rossoctl platform +- [operator](https://github.com/rossoctl/operator) — Kubernetes operator for sidecar injection (includes the admission webhook) ## License diff --git a/SECURITY.md b/SECURITY.md index 628c8c269..ada79feb1 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -40,4 +40,4 @@ This project implements several security controls: For deployment security configuration, see: - [AuthBridge README](authbridge/README.md) - Authentication bridge architecture -- [kagenti-operator](https://github.com/kagenti/kagenti-operator) - Admission webhook configuration (migrated from this repo) +- [operator](https://github.com/rossoctl/operator) - Admission webhook configuration (migrated from this repo) diff --git a/aiac/docs/specs/ARCHITECTURE-SUMMARY.md b/aiac/docs/specs/ARCHITECTURE-SUMMARY.md index 95ade7047..5ad1adedd 100644 --- a/aiac/docs/specs/ARCHITECTURE-SUMMARY.md +++ b/aiac/docs/specs/ARCHITECTURE-SUMMARY.md @@ -2,7 +2,7 @@ ## Abstract -AI-based Access Control (AIAC) is a Kagenti platform extension that automates RBAC/ABAC policy +AI-based Access Control (AIAC) is a Rossoctl platform extension that automates RBAC/ABAC policy enforcement for AI agents running on Kubernetes. A LangGraph-based AI agent continuously translates a natural-language access control policy — stored in a vector knowledge base — into concrete permission configurations in the active Policy Decision Point (PDP), eliminating manual policy @@ -14,7 +14,7 @@ management (subjects, roles, services). ## Problem Description -Kagenti AI agents call services across a shared platform. Every call must carry a token scoped to +Rossoctl AI agents call services across a shared platform. Every call must carry a token scoped to exactly the permissions the caller's role entitles on the target service. Without a dedicated policy management layer, access policy ends up scattered across per-deployment configuration, creating three compounding problems: @@ -108,7 +108,7 @@ Eight components across five Kubernetes Pods plus a Python library layer, all im │ | (𝘶𝘴𝘦𝘳𝘴, 𝘳𝘰𝘭𝘦𝘴, 𝘤𝘭𝘪𝘦𝘯𝘵𝘴) (𝘈𝘶𝘵𝘩𝘰𝘳𝘪𝘻𝘢𝘵𝘪𝘰𝘯𝘗𝘰𝘭𝘪𝘤𝘺 𝘊𝘙) ┌──────────────┼──────────────────────┼───────────────────┐ -│ Kagenti Interface Pod │ │ +│ Rossoctl Interface Pod │ │ │ │ │ │ │ ┌───────┴──────┐ ┌────────┴───────┐ │ │ │ IdP Config │ │ PDP Policy │ │ @@ -154,12 +154,12 @@ All inter-pod traffic is Kubernetes ClusterIP. External access is exclusively vi --- -## Kagenti / Keycloak / OPA Interfaces +## Rossoctl / Keycloak / OPA Interfaces -**AIAC ↔ Kagenti platform** +**AIAC ↔ Rossoctl platform** The AIAC Agent reads `AgentRuntime` and `AgentCard` custom resources from the Kubernetes API to extract service metadata during UC-1 service onboarding. The `aiac.idp.library` and -`aiac.pdp.library` Python packages are the integration surface for other Kagenti components +`aiac.pdp.library` Python packages are the integration surface for other Rossoctl components needing typed access to IdP configuration and PDP policy state. **AIAC ↔ Keycloak** diff --git a/aiac/docs/specs/PRD.md b/aiac/docs/specs/PRD.md index 69f8ef6de..1f3be5a8b 100644 --- a/aiac/docs/specs/PRD.md +++ b/aiac/docs/specs/PRD.md @@ -2,7 +2,7 @@ ## Abstract -AI-based Access Control (AIAC) is a Kagenti platform extension that automates RBAC/ABAC policy +AI-based Access Control (AIAC) is a Rossoctl platform extension that automates RBAC/ABAC policy enforcement for AI agents running on Kubernetes. A LangGraph-based AI agent continuously translates a natural-language access control policy — stored in a vector knowledge base — into concrete permission configurations in the active Policy Decision Point (PDP), eliminating manual policy @@ -14,7 +14,7 @@ management (subjects, roles, services). ## 1. Problem Description -Kagenti AI agents call services across a shared platform. Every call must carry a token scoped to +Rossoctl AI agents call services across a shared platform. Every call must carry a token scoped to exactly the permissions the caller's role entitles on the target service. Without a dedicated policy management layer, access policy ends up scattered across per-deployment configuration, creating three compounding problems: @@ -125,7 +125,7 @@ Eight components across five Kubernetes Pods plus a Python library layer, all im │ | (𝘶𝘴𝘦𝘳𝘴, 𝘳𝘰𝘭𝘦𝘴, 𝘤𝘭𝘪𝘦𝘯𝘵𝘴) (𝘈𝘶𝘵𝘩𝘰𝘳𝘪𝘻𝘢𝘵𝘪𝘰𝘯𝘗𝘰𝘭𝘪𝘤𝘺 𝘊𝘙) ┌──────────────┼──────────────────────┼───────────────────┐ -│ Kagenti Interface Pod │ │ +│ Rossoctl Interface Pod │ │ │ │ │ │ │ ┌───────┴──────┐ ┌────────┴───────┐ │ │ │ IdP Config │ │ PDP Policy │ │ @@ -271,8 +271,8 @@ All inter-pod traffic is Kubernetes ClusterIP. External access is exclusively vi | Component | Called by | Calls | Returns | |-----------|-----------|-------|---------| -| IdP Configuration Service (in Kagenti Interface Pod) | `aiac.idp.configuration.api` | Keycloak Admin REST API | Raw Keycloak JSON (generic endpoint names) | -| PDP Policy Writer — OPA (in Kagenti Interface Pod) | `aiac.pdp.policy.library` | Kubernetes CR (`AuthorizationPolicy`) | 204 on success | +| IdP Configuration Service (in Rossoctl Interface Pod) | `aiac.idp.configuration.api` | Keycloak Admin REST API | Raw Keycloak JSON (generic endpoint names) | +| PDP Policy Writer — OPA (in Rossoctl Interface Pod) | `aiac.pdp.policy.library` | Kubernetes CR (`AuthorizationPolicy`) | 204 on success | | Policy Store (StatefulSet `aiac-policy-store`) | `aiac.policy.store.library` | SQLite (`agent_policies` table, in-memory cache) | `AgentPolicyModel` / `PolicyModel` on read; 204 on write | | Policy Computation Engine (`aiac.policy.computation`) | AIAC Agent sub-UC agents | `aiac.idp.configuration.api`, `aiac.policy.store.library`, `aiac.pdp.policy.library` | None (fire-and-forget; logs exceptions) | | `aiac.idp.configuration.models` | `aiac.idp.configuration.api`, `aiac.policy.model`, AIAC Agent | — | Pydantic model definitions for IdP entities (Subject, Role, Service, Scope) | @@ -287,7 +287,7 @@ All inter-pod traffic is Kubernetes ClusterIP. External access is exclusively vi ### Key architectural decisions -- **Stateless PDP services are co-located in the Kagenti Interface Pod; the stateful Policy Store is separate.** IdP Configuration Service and PDP Policy Writer run as two containers in the Interface Pod, sharing a Kubernetes ServiceAccount. The Policy Store is a dedicated single-replica StatefulSet (`aiac-policy-store`) with its own PVC — decoupled from the Interface Pod's restart lifecycle. Three ClusterIP Services (`aiac-pdp-config-service:7071`, `aiac-pdp-policy-service:7072`, `aiac-policy-store-service:7074`) provide stable addressing. +- **Stateless PDP services are co-located in the Rossoctl Interface Pod; the stateful Policy Store is separate.** IdP Configuration Service and PDP Policy Writer run as two containers in the Interface Pod, sharing a Kubernetes ServiceAccount. The Policy Store is a dedicated single-replica StatefulSet (`aiac-policy-store`) with its own PVC — decoupled from the Interface Pod's restart lifecycle. Three ClusterIP Services (`aiac-pdp-config-service:7071`, `aiac-pdp-policy-service:7072`, `aiac-policy-store-service:7074`) provide stable addressing. - **Policy Computation Engine is a library, not a service.** `aiac.policy.computation` runs in-process within the AIAC Agent pod. It requires no Kubernetes deployment, no container image, and no ClusterIP Service. Sub-agents call `compute_and_apply(rules)` directly. - **One CR + one SQLite store, distinct owners, distinct purposes.** The Policy Store owns a SQLite `agent_policies` table (backed by a 1 Gi RWO PVC) holding structured `AgentPolicyModel` data — the source of truth for policy state, served from an in-memory cache. The `AuthorizationPolicy` CR (one total, owned by the PDP Policy Writer) holds derived Rego packages for OPA runtime. The two services have no dependency on each other; both are driven by the PCE via their respective libraries. - **`aiac.pdp.policy.library` has one caller: `aiac.policy.computation`.** AIAC Agent sub-agents do not call the PDP Policy Library directly; they call `compute_and_apply()` instead. This centralises all Policy Store ↔ PDP Policy Writer coordination. @@ -313,11 +313,11 @@ All inter-pod traffic is Kubernetes ClusterIP. External access is exclusively vi --- -## 6. Kagenti / Keycloak / OPA Interfaces +## 6. Rossoctl / Keycloak / OPA Interfaces -**AIAC ↔ Kagenti platform** +**AIAC ↔ Rossoctl platform** The AIAC Agent reads `AgentRuntime` and `AgentCard` custom resources from the Kubernetes API to -extract service metadata during UC-1 service onboarding. The `aiac.idp.configuration` and `aiac.pdp.policy.library` Python packages are the integration surface for other Kagenti components needing typed access to the IdP and PDP respectively. +extract service metadata during UC-1 service onboarding. The `aiac.idp.configuration` and `aiac.pdp.policy.library` Python packages are the integration surface for other Rossoctl components needing typed access to the IdP and PDP respectively. **AIAC ↔ Keycloak** The IdP Configuration Service proxies Keycloak Admin REST endpoints under generic entity names (subjects, roles, services, scopes, assignments). Read endpoints include per-service role and scope enrichment. The Keycloak SPI listener publishes entity lifecycle events to NATS; it is a separate component outside the AIAC codebase. @@ -336,7 +336,7 @@ See Section 7.5 (Event Broker) and Section 8 (Deployment) for subject names and ### 7.1 IdP Configuration Service -FastAPI service (`0.0.0.0:7071`) co-located with the PDP Policy Writer in the **Kagenti Interface Pod**. Manages IdP (Keycloak) entity data (subjects, roles, services, scopes) via Keycloak Admin REST API. Exposes read and write endpoints for configuration entities. Stateless. All endpoints except `/health` require a `?realm=` query parameter; returns `422` if absent. `/health` requires no realm parameter — it uses `KEYCLOAK_ADMIN_REALM` directly. `KeycloakAdmin` instances are created lazily per realm and cached in a thread-safe map; the admin always authenticates via the realm in `KEYCLOAK_ADMIN_REALM`. +FastAPI service (`0.0.0.0:7071`) co-located with the PDP Policy Writer in the **Rossoctl Interface Pod**. Manages IdP (Keycloak) entity data (subjects, roles, services, scopes) via Keycloak Admin REST API. Exposes read and write endpoints for configuration entities. Stateless. All endpoints except `/health` require a `?realm=` query parameter; returns `422` if absent. `/health` requires no realm parameter — it uses `KEYCLOAK_ADMIN_REALM` directly. `KeycloakAdmin` instances are created lazily per realm and cached in a thread-safe map; the admin always authenticates via the realm in `KEYCLOAK_ADMIN_REALM`. **Full spec:** [components/idp-configuration-service.md](components/idp-configuration-service.md) @@ -344,7 +344,7 @@ FastAPI service (`0.0.0.0:7071`) co-located with the PDP Policy Writer in the ** ### 7.2 PDP Policy Writer -FastAPI service (`0.0.0.0:7072`, `aiac-pdp-policy-opa`) co-located with the IdP Configuration Service in the **Kagenti Interface Pod**. Writes LLM-generated Rego packages to an `AuthorizationPolicy` Kubernetes CR. Each AuthBridge OPA plugin instance fetches its Rego packages from the CR at startup. +FastAPI service (`0.0.0.0:7072`, `aiac-pdp-policy-opa`) co-located with the IdP Configuration Service in the **Rossoctl Interface Pod**. Writes LLM-generated Rego packages to an `AuthorizationPolicy` Kubernetes CR. Each AuthBridge OPA plugin instance fetches its Rego packages from the CR at startup. **Full spec:** [components/pdp-policy-writer-opa.md](components/pdp-policy-writer-opa.md) @@ -408,7 +408,7 @@ FastAPI + LangGraph service (`0.0.0.0:7070`). Receives automated triggers via th | Policy Update | `aiac.apply.policy.build`, `/apply/policy/rebuild` (HTTP) | Build sub-agent or Rebuild sub-agent (alternative) | | Role Update | `aiac.apply.role.{id}` | Role sub-agent | -All sub-agent `StateGraph` instances are logically separated modules running within a single pod and process. Sub-UC agents produce `list[PolicyRule]` and call `compute_and_apply(rules)` — they do not call `aiac.policy.store.library` or `aiac.pdp.policy.library` directly. The **Policy Update** sub-agents compute a minimal rule delta between the current ChromaDB policy and live OPA state. The **Rebuild** variant additionally clears the Policy Store and all OPA policy rules before recomputing. The **Role Update** orchestrator computes rules for all services affected by the role change. The **Service Onboarding** orchestrator classifies the new service via the pod's `kagenti.io/type` label (for agents reads the `AgentCard` CR; for tools calls `tools/list` on the MCP endpoint discovered via K8s Service label lookup), then computes rules and calls `compute_and_apply`. Stateless; changes are applied immediately. Integrated retry with differentiated error codes per upstream. +All sub-agent `StateGraph` instances are logically separated modules running within a single pod and process. Sub-UC agents produce `list[PolicyRule]` and call `compute_and_apply(rules)` — they do not call `aiac.policy.store.library` or `aiac.pdp.policy.library` directly. The **Policy Update** sub-agents compute a minimal rule delta between the current ChromaDB policy and live OPA state. The **Rebuild** variant additionally clears the Policy Store and all OPA policy rules before recomputing. The **Role Update** orchestrator computes rules for all services affected by the role change. The **Service Onboarding** orchestrator classifies the new service via the pod's `rossoctl.io/type` label (for agents reads the `AgentCard` CR; for tools calls `tools/list` on the MCP endpoint discovered via K8s Service label lookup), then computes rules and calls `compute_and_apply`. Stateless; changes are applied immediately. Integrated retry with differentiated error codes per upstream. **Full spec:** [components/aiac-agent.md](components/aiac-agent.md) @@ -452,7 +452,7 @@ Four separate manifest files: | File | Contents | |------|----------| -| `aiac/k8s/pdp-interface-deployment.yaml` | `aiac-pdp-config` ConfigMap + Kagenti Interface Pod Deployment (IdP Configuration Service container + PDP Policy Writer container) + two ClusterIP Services (`aiac-pdp-config-service:7071`, `aiac-pdp-policy-service:7072`) | +| `aiac/k8s/pdp-interface-deployment.yaml` | `aiac-pdp-config` ConfigMap + Rossoctl Interface Pod Deployment (IdP Configuration Service container + PDP Policy Writer container) + two ClusterIP Services (`aiac-pdp-config-service:7071`, `aiac-pdp-policy-service:7072`) | | `aiac/k8s/policy-store-statefulset.yaml` | `aiac-policy-store` StatefulSet (Policy Store container) + `volumeClaimTemplate` (1 Gi, `ReadWriteOnce`, mounted at `/data`) + headless Service + `aiac-policy-store-service:7074` ClusterIP Service | | `aiac/k8s/agent-deployment.yaml` | Agent Pod Deployment (aiac-init container + AIAC Agent container) + ClusterIP Service | | `aiac/k8s/event-broker-deployment.yaml` _(pending)_ | Event Broker Pod Deployment (NATS JetStream) + ClusterIP Service | @@ -465,10 +465,10 @@ The two Interface Pod containers mount `aiac-pdp-config` (KEYCLOAK_URL, KEYCLOAK Built independently. No entry in the repo's `build.yaml` CI matrix. ```bash -# Build IdP Configuration Service (Kagenti Interface Pod container 1) +# Build IdP Configuration Service (Rossoctl Interface Pod container 1) docker build -f aiac/src/aiac/idp/service/configuration/keycloak/Dockerfile -t aiac-pdp-config:latest aiac/src/ -# Build PDP Policy Writer — Phase 1 mock (Kagenti Interface Pod container 2; writes Rego to filesystem) +# Build PDP Policy Writer — Phase 1 mock (Rossoctl Interface Pod container 2; writes Rego to filesystem) docker build -f aiac/src/aiac/pdp/service/policy/keycloak/Dockerfile -t aiac-pdp-policy-keycloak:latest aiac/src/ # Build PDP Policy Writer — Phase 2 OPA (replaces mock via issue 4.18; writes to AuthorizationPolicy CR) @@ -495,7 +495,7 @@ metadata: name: aiac-pdp-config data: KEYCLOAK_URL: "http://keycloak-service.keycloak.svc:8080" - KEYCLOAK_REALM: "kagenti" + KEYCLOAK_REALM: "rossoctl" KEYCLOAK_ADMIN_REALM: "master" AIAC_PDP_CONFIG_URL: "http://aiac-pdp-config-service:7071" AIAC_PDP_POLICY_URL: "http://aiac-pdp-policy-service:7072" @@ -571,7 +571,7 @@ Beyond the marker-gated pytest tests above, individual integration tests are spe |---|---|---| | PDP Policy Writer — `generate_rego.py` | Standalone launcher (no Docker) that boots the OPA stub locally, applies a `PolicyModel` through `aiac.pdp.policy.library`, and writes the generated Rego to a known directory for manual inspection. Write-only; not `@pytest.mark.integration`. | [integration-test/pdp-policy-writer.md](integration-test/pdp-policy-writer.md) | | `policy-pipeline` — `policy_pipeline.py` | Standalone launcher (no Docker) driving the full identity→policy pipeline — provisions a Keycloak realm + entities, runs the three PRB mappings, applies via the PCE, and writes the generated Rego to a known directory for manual inspection. Write-only; not `@pytest.mark.integration`. | [integration-test/policy-pipeline.md](integration-test/policy-pipeline.md) | -| `uc1-onboarding-pipeline` — `test_uc1_onboarding_pipeline.py` | Discovery-driven sibling of `policy-pipeline` validating the **phase-1** deliverable: deploys the real `github-agent` + a simplified `github-tool` to a live Kagenti cluster, drives **real UC-1 onboarding** (`POST /apply/service/{id}`) to infer roles/scopes, and asserts the generated Rego with `opa eval`. Same scenario facts/tables as `policy-pipeline`; Rego is semantically similar (not byte-identical). `@pytest.mark.integration`. | [integration-test/uc1-onboarding-pipeline.md](integration-test/uc1-onboarding-pipeline.md) | +| `uc1-onboarding-pipeline` — `test_uc1_onboarding_pipeline.py` | Discovery-driven sibling of `policy-pipeline` validating the **phase-1** deliverable: deploys the real `github-agent` + a simplified `github-tool` to a live Rossoctl cluster, drives **real UC-1 onboarding** (`POST /apply/service/{id}`) to infer roles/scopes, and asserts the generated Rego with `opa eval`. Same scenario facts/tables as `policy-pipeline`; Rego is semantically similar (not byte-identical). `@pytest.mark.integration`. | [integration-test/uc1-onboarding-pipeline.md](integration-test/uc1-onboarding-pipeline.md) | Tracking issues: the live-Keycloak pytest integration tests in `testing/5.1-integration-tests.md`; the PDP Policy Writer integration test in `testing/5.2-pdp-writer-integration-test.md`; the policy-pipeline integration test in `testing/5.3-policy-pipeline-integration-test.md`; the UC-1 onboarding pipeline integration test in `testing/5.4-uc1-onboarding-integration-test.md`. diff --git a/aiac/docs/specs/components/aiac-agent/uc1-service-onboarding.md b/aiac/docs/specs/components/aiac-agent/uc1-service-onboarding.md index cacc53cae..1948779d9 100644 --- a/aiac/docs/specs/components/aiac-agent/uc1-service-onboarding.md +++ b/aiac/docs/specs/components/aiac-agent/uc1-service-onboarding.md @@ -81,11 +81,11 @@ START → classify_service → [analyze_agent | analyze_tool] → provision_serv ### Nodes -- **`classify_service`**: resolves identity + determines service type from the operator's authoritative `kagenti.io/type` label (values `agent`/`tool`) — **not** from the `entity_id` format. +- **`classify_service`**: resolves identity + determines service type from the operator's authoritative `rossoctl.io/type` label (values `agent`/`tool`) — **not** from the `entity_id` format. 1. Store `service_id = trigger.entity_id` (Keycloak `client_id`). - 2. Resolve identity: call `get_service(service_id)` from `aiac.idp.configuration.api` → `client.name`, which the kagenti-operator sets to `"{namespace}/{workload_name}"` for every workload (agents and tools, SPIRE-enabled or not). Split on the first `/` → store `namespace` and `workload_name`. `502` if `client.name` has no `/` (namespace unrecoverable). + 2. Resolve identity: call `get_service(service_id)` from `aiac.idp.configuration.api` → `client.name`, which the operator sets to `"{namespace}/{workload_name}"` for every workload (agents and tools, SPIRE-enabled or not). Split on the first `/` → store `namespace` and `workload_name`. `502` if `client.name` has no `/` (namespace unrecoverable). 3. LIST pods in `namespace`; select the pod owned by `workload_name` via `ownerReferences` (Deployment → ReplicaSet name prefix, or `StatefulSet`/`Sandbox` name match). `502` on Kubernetes API failure or no matching pod. - 4. Read the `kagenti.io/type` label on that pod and normalize it to a `ServiceType` + 4. Read the `rossoctl.io/type` label on that pod and normalize it to a `ServiceType` member via `ServiceType(label.capitalize())` — the label is lowercase (`agent`/`tool`); `ServiceType` values are capitalized (`Agent`/`Tool`): - `agent` → `ServiceType.AGENT`; route to `analyze_agent`. @@ -93,10 +93,10 @@ START → classify_service → [analyze_agent | analyze_tool] → provision_serv - Absent or any other value (normalization raises `ValueError`) → `502` (inconsistent deployment). > K8s access: `list` on `pods` in the target namespace (both paths). - > `kagenti.io/type` is authoritative — applied by the kagenti-operator (via the AgentRuntime CR) and propagated to pod labels; it is the operator's own agent/tool discriminator (`SkipReason`, kagenti-operator `internal/clientreg/names.go`). The operator only registers a Keycloak client for a workload that already carries this label, so it is effectively guaranteed for operator-registered clients; a missing/invalid value still fails loud (`502`, naming the workload + label). The `entity_id` format (SPIFFE vs plain) reflects whether SPIRE is enabled, **not** the service type, so it is not used for classification. + > `rossoctl.io/type` is authoritative — applied by the operator (via the AgentRuntime CR) and propagated to pod labels; it is the operator's own agent/tool discriminator (`SkipReason`, operator `internal/clientreg/names.go`). The operator only registers a Keycloak client for a workload that already carries this label, so it is effectively guaranteed for operator-registered clients; a missing/invalid value still fails loud (`502`, naming the workload + label). The `entity_id` format (SPIFFE vs plain) reflects whether SPIRE is enabled, **not** the service type, so it is not used for classification. - **`analyze_agent`**: non-LLM node; reads AgentCard CR. - 1. LIST `AgentCard` CRs (`agent.kagenti.dev/v1alpha1`) in `namespace`; find the one matching `workload_name`. + 1. LIST `AgentCard` CRs (`agent.rossoctl.dev/v1alpha1`) in `namespace`; find the one matching `workload_name`. 2. **AgentCard found** → produce `ServiceProvision`: - `roles`: `[RoleDefinition(name=f"{workloadName}.agent", description="Agent role")]` - `scopes`: `[ScopeDefinition(name=f"{workloadName}.{skill.name}", description=skill.description) for skill in card.skills]` @@ -106,12 +106,12 @@ START → classify_service → [analyze_agent | analyze_tool] → provision_serv - `scopes`: `[ScopeDefinition(name=f"{workloadName}.access", description="Default access scope")]` - `reasoning`: `"partial: no AgentCard found, default scope assigned"` - > K8s access: `list` on `agentcards.agent.kagenti.dev` in the target namespace. + > K8s access: `list` on `agentcards.agent.rossoctl.dev` in the target namespace. - **`analyze_tool`**: non-LLM node; discovers MCP tools. `namespace` + `workload_name` are already resolved by `classify_service` (from the `client.name` split). MCP endpoint lookup uses the **hybrid Keycloak→K8s strategy** decided in issue `docs/gh-issues/6.2-analyze-tool-lookup-strategy.md`: the Keycloak client name supplied the key `{namespace, workload_name}`; K8s supplies the reachable endpoint. 1. Locate MCP endpoint: a. GET the K8s `Service` named `workload_name` in `namespace` (operator convention: Service name == workload name). - b. Require the `protocol.kagenti.io/mcp` label present on that Service; `502` (actionable) if absent — the label is applied at deploy time, not stamped by the operator. + b. Require the `protocol.rossoctl.io/mcp` label present on that Service; `502` (actionable) if absent — the label is applied at deploy time, not stamped by the operator. c. Build `http://{workload_name}.{namespace}.svc.cluster.local:{port}/mcp`, where `port` is the Service's first port (not hardcoded). 2. Call `tools/list` (HTTP POST, MCP protocol) on the resolved endpoint. 3. Produce `ServiceProvision`: @@ -121,10 +121,10 @@ START → classify_service → [analyze_agent | analyze_tool] → provision_serv 4. Returns `502` on Service/label lookup failure or MCP call failure. > K8s access: `get` on `services` in the workload namespace (tool path). Identity is resolved by `classify_service` (config API). - > MCP path convention: all MCP tool services must serve at `/mcp` and carry the `protocol.kagenti.io/mcp` label. This label is a **deploy-time prerequisite** — the kagenti-operator does not stamp it today; automatic stamping is requested upstream (`docs/gh-issues/kagenti-operator-mcp-label-stamping.md`). Until then it must be applied at deploy time; `analyze_tool` fails loud (`502`, naming the workload + missing label) if it is absent. + > MCP path convention: all MCP tool services must serve at `/mcp` and carry the `protocol.rossoctl.io/mcp` label. This label is a **deploy-time prerequisite** — the operator does not stamp it today; automatic stamping is requested upstream (`docs/gh-issues/operator-mcp-label-stamping.md`). Until then it must be applied at deploy time; `analyze_tool` fails loud (`502`, naming the workload + missing label) if it is absent. - **`provision_service`**: non-LLM node; calls `create_service_role` and `create_service_scope` from `aiac.idp.configuration.api` for each entry in `ServiceProvision`. Reads `service_id` from state. Writes are **idempotent** (create-or-get). - - Also persists the discovered `service_type` onto the Keycloak client via `Configuration.set_service_type(service, service_type)`, which stores it as the **`client.type`** attribute. This is the **authoritative origin** of the attribute that the IdP library's `Service._resolve_keycloak_fields` reads back (see the IdP library spec's type-resolution precedence). No case mapping is needed here: `service_type` is a `ServiceType` (values `Agent`/`Tool`), already matching `client.type` and `Service.type`. Case normalization happens once, upstream, when `classify_service` reads the lowercase `kagenti.io/type` label. + - Also persists the discovered `service_type` onto the Keycloak client via `Configuration.set_service_type(service, service_type)`, which stores it as the **`client.type`** attribute. This is the **authoritative origin** of the attribute that the IdP library's `Service._resolve_keycloak_fields` reads back (see the IdP library spec's type-resolution precedence). No case mapping is needed here: `service_type` is a `ServiceType` (values `Agent`/`Tool`), already matching `client.type` and `Service.type`. Case normalization happens once, upstream, when `classify_service` reads the lowercase `rossoctl.io/type` label. ### State: `OnboardingProvisionState` diff --git a/aiac/docs/specs/components/idp-configuration-service.md b/aiac/docs/specs/components/idp-configuration-service.md index fef5db1f6..e62ed9267 100644 --- a/aiac/docs/specs/components/idp-configuration-service.md +++ b/aiac/docs/specs/components/idp-configuration-service.md @@ -115,7 +115,7 @@ Environment variables (injected via Kubernetes Deployment manifest): - Bind: `0.0.0.0:7071` - Base image: `python:3.12-slim` - Kubernetes ClusterIP Service: `aiac-pdp-config-service:7071` -- Deployment: co-located with PDP Policy Writer as a container in the **Kagenti Interface Pod** (`pdp-interface-deployment.yaml`) +- Deployment: co-located with PDP Policy Writer as a container in the **Rossoctl Interface Pod** (`pdp-interface-deployment.yaml`) - Python library: `aiac.idp.library.configuration` ## Dependencies (`requirements.txt`) diff --git a/aiac/docs/specs/components/keycloak-service.md b/aiac/docs/specs/components/keycloak-service.md index 362be1761..d04a1f613 100644 --- a/aiac/docs/specs/components/keycloak-service.md +++ b/aiac/docs/specs/components/keycloak-service.md @@ -39,7 +39,7 @@ Environment variables (injected via Kubernetes Deployment manifest): | Variable | Required | Description | |----------|----------|-------------| | `KEYCLOAK_URL` | Yes | Keycloak base URL, e.g. `http://keycloak-service.keycloak.svc:8080` | -| `KEYCLOAK_REALM` | Yes | Realm name, e.g. `kagenti` | +| `KEYCLOAK_REALM` | Yes | Realm name, e.g. `rossoctl` | | `KEYCLOAK_ADMIN_USERNAME` | Yes | Admin username (from `keycloak-admin-secret`) | | `KEYCLOAK_ADMIN_PASSWORD` | Yes | Admin password (from `keycloak-admin-secret`) | diff --git a/aiac/docs/specs/components/library-idp.md b/aiac/docs/specs/components/library-idp.md index 97d5f8572..b4a98b062 100644 --- a/aiac/docs/specs/components/library-idp.md +++ b/aiac/docs/specs/components/library-idp.md @@ -90,9 +90,9 @@ Represents a service (Keycloak: `client`). 2. Otherwise the Keycloak client attribute **`client.type`** ∈ {`Agent`, `Tool`} — a **plain string**. Client attribute values are plain strings; a **list** value (e.g. `["Agent"]`, the shape realm-role attributes use) fails the check and resolves to `None`. Capitalization matches the `ServiceType` values. 3. Otherwise `None`. -The attribute is set via `Configuration.set_service_type` (below); its authoritative origin is UC1 Service Onboarding — `classify_service` **discovers** the type from the operator's `kagenti.io/type` label and `provision_service` **persists** it onto the client via `set_service_type` (see the aiac-agent UC1 spec). There is **no** `spiffe://` clientId fallback and **no** description-keyword inference — typing is `client.type`-attribute-only. (The former `spiffe:// ⇒ Agent` fallback was **removed**: a `spiffe://` clientId indicates a SPIRE-enabled workload, **not** necessarily an agent — it could mis-type a SPIRE-enabled tool — so clients without a `client.type` attribute now resolve to `None`.) +The attribute is set via `Configuration.set_service_type` (below); its authoritative origin is UC1 Service Onboarding — `classify_service` **discovers** the type from the operator's `rossoctl.io/type` label and `provision_service` **persists** it onto the client via `set_service_type` (see the aiac-agent UC1 spec). There is **no** `spiffe://` clientId fallback and **no** description-keyword inference — typing is `client.type`-attribute-only. (The former `spiffe:// ⇒ Agent` fallback was **removed**: a `spiffe://` clientId indicates a SPIRE-enabled workload, **not** necessarily an agent — it could mis-type a SPIRE-enabled tool — so clients without a `client.type` attribute now resolve to `None`.) -> **`ServiceType`** (`aiac.idp.configuration.models`) is a `str` enum — `AGENT = "Agent"`, `TOOL = "Tool"` — shared by `Service.type`, `set_service_type`, and the aiac-agent sub-agents (one vocabulary, no duplication). Values are capitalized to match the `client.type` attribute; because it subclasses `str`, `ServiceType.AGENT == "Agent"`, so it is a drop-in for the former `Literal["Agent", "Tool"]`. The operator's lowercase `kagenti.io/type` pod label is normalized to a member via `ServiceType(label.capitalize())` in UC1 `classify_service`. +> **`ServiceType`** (`aiac.idp.configuration.models`) is a `str` enum — `AGENT = "Agent"`, `TOOL = "Tool"` — shared by `Service.type`, `set_service_type`, and the aiac-agent sub-agents (one vocabulary, no duplication). Values are capitalized to match the `client.type` attribute; because it subclasses `str`, `ServiceType.AGENT == "Agent"`, so it is a drop-in for the former `Literal["Agent", "Tool"]`. The operator's lowercase `rossoctl.io/type` pod label is normalized to a member via `ServiceType(label.capitalize())` in UC1 `classify_service`. #### `Scope` @@ -282,7 +282,7 @@ Read from a `.env` file co-located with `api.py` (`aiac/src/aiac/idp/configurati ```python from aiac.idp.configuration.api import Configuration -cfg = Configuration.for_realm("kagenti") +cfg = Configuration.for_realm("rossoctl") subjects = cfg.get_subjects() for s in subjects: print(s.username, s.email) diff --git a/aiac/docs/specs/components/pdp-policy-keycloak-service.md b/aiac/docs/specs/components/pdp-policy-keycloak-service.md index afa72a7b8..e913f0178 100644 --- a/aiac/docs/specs/components/pdp-policy-keycloak-service.md +++ b/aiac/docs/specs/components/pdp-policy-keycloak-service.md @@ -6,7 +6,7 @@ ## Description A FastAPI web service that applies RBAC policy changes to Keycloak by managing composite role mappings. Roles are made composites of service (client) permissions (roles), so that any subject (user) assigned a role automatically inherits the associated service permissions. Stateless — no caching. -This is the **Phase 1** implementation of the PDP Policy Writer. It is deployed as a container in the **Kagenti Interface Pod** alongside the IdP Configuration Service, behind the `aiac-pdp-policy-service:7072` ClusterIP. Phase 2 replaces only this container image (`aiac-pdp-policy-keycloak` → `aiac-pdp-policy-opa`) within the same pod. The service name and port remain stable so the AIAC Agent and library require no reconfiguration. +This is the **Phase 1** implementation of the PDP Policy Writer. It is deployed as a container in the **Rossoctl Interface Pod** alongside the IdP Configuration Service, behind the `aiac-pdp-policy-service:7072` ClusterIP. Phase 2 replaces only this container image (`aiac-pdp-policy-keycloak` → `aiac-pdp-policy-opa`) within the same pod. The service name and port remain stable so the AIAC Agent and library require no reconfiguration. ## Endpoints @@ -33,7 +33,7 @@ All endpoints return `502 Bad Gateway` with a JSON error body if the Keycloak Ad | Variable | Required | Description | |----------|----------|-------------| | `KEYCLOAK_URL` | Yes | Keycloak base URL, e.g. `http://keycloak-service.keycloak.svc:8080` | -| `KEYCLOAK_REALM` | Yes | Realm name, e.g. `kagenti` | +| `KEYCLOAK_REALM` | Yes | Realm name, e.g. `rossoctl` | | `KEYCLOAK_ADMIN_USERNAME` | Yes | Admin username (from `keycloak-admin-secret`) | | `KEYCLOAK_ADMIN_PASSWORD` | Yes | Admin password (from `keycloak-admin-secret`) | @@ -44,7 +44,7 @@ All endpoints return `502 Bad Gateway` with a JSON error body if the Keycloak Ad - Bind: `0.0.0.0:7072` - Base image: `python:3.12-slim` - Kubernetes ClusterIP Service: `aiac-pdp-policy-service:7072` -- Deployment: co-located with IdP Configuration Service as a container in the **Kagenti Interface Pod** (`pdp-interface-deployment.yaml`) +- Deployment: co-located with IdP Configuration Service as a container in the **Rossoctl Interface Pod** (`pdp-interface-deployment.yaml`) ## Dependencies (`requirements.txt`) diff --git a/aiac/docs/specs/components/pdp-policy-writer-opa.md b/aiac/docs/specs/components/pdp-policy-writer-opa.md index 797346e4a..65c3060a8 100644 --- a/aiac/docs/specs/components/pdp-policy-writer-opa.md +++ b/aiac/docs/specs/components/pdp-policy-writer-opa.md @@ -6,7 +6,7 @@ ## Description A FastAPI web service that translates a **Policy Model** into OPA Rego packages and writes them to an `AuthorizationPolicy` Kubernetes Custom Resource. The OPA plugin embedded in each AuthBridge instance fetches the Rego packages relevant to its pod from this CR at startup. -The service is deployed as a container in the **Kagenti Interface Pod** alongside the IdP Configuration Service, behind the `aiac-pdp-policy-service:7072` ClusterIP. +The service is deployed as a container in the **Rossoctl Interface Pod** alongside the IdP Configuration Service, behind the `aiac-pdp-policy-service:7072` ClusterIP. The service has no dependency on Keycloak. All Keycloak operations (entity reads) are handled by the **IdP Configuration Service** and its library (`aiac.idp.library.configuration`). @@ -242,7 +242,7 @@ For local development, the `kubernetes` client falls back to `~/.kube/config` au - Bind: `0.0.0.0:7072` - Base image: `python:3.12-slim` - Kubernetes ClusterIP Service: `aiac-pdp-policy-service:7072` -- Deployment: co-located with IdP Configuration Service as a container in the **Kagenti Interface Pod** (`pdp-interface-deployment.yaml`) +- Deployment: co-located with IdP Configuration Service as a container in the **Rossoctl Interface Pod** (`pdp-interface-deployment.yaml`) --- diff --git a/aiac/docs/specs/demo/github-agent.md b/aiac/docs/specs/demo/github-agent.md index e8d34a871..b2b39ac7f 100644 --- a/aiac/docs/specs/demo/github-agent.md +++ b/aiac/docs/specs/demo/github-agent.md @@ -42,7 +42,7 @@ RFC-8693 token exchange, and the `github-tool` MitM swaps the exchanged token fo - Existing (issue-only) agent card: [`../../analysis/github-agent-card.json`](../../analysis/github-agent-card.json) - `github-tool` MCP tool catalog (44 tools): [`../../analysis/github-mcp-tools-summary.json`](../../analysis/github-mcp-tools-summary.json) - Reference agent: `agent-examples/a2a/git_issue_agent/` -- Reference deployment: `kagenti-extensions/authbridge/demos/github-issue/k8s/` +- Reference deployment: `rossocortex/authbridge/demos/github-issue/k8s/` - **Sibling tool spec (UC-1 onboarding fixture):** [`github-tool.md`](github-tool.md) — a simplified 4-tool stub (`source-read`, `source-write`, `issues-read`, `issues-write`) deployed as Service `github-tool`. **This is not the tool this agent connects to.** The agent connects to the production @@ -57,7 +57,7 @@ Reuse the `git_issue_agent` stack verbatim — do not introduce a new framework: - **A2A SDK 1.x** server (route factories, `AgentInterface`, snake_case card fields). Binds `0.0.0.0` on `PORT` (default **8000**). `create_jsonrpc_routes(..., enable_v0_3_compat=True)` — **required** - because Kagenti uses A2A 0.3 client libraries — plus the agent card at both + because Rossoctl uses A2A 0.3 client libraries — plus the agent card at both `/.well-known/agent-card.json` and legacy `/.well-known/agent.json`. - **CrewAI** orchestration (`Agent`/`Crew`/`Task`, `Process.sequential`), LLM via **litellm** (`crewai.LLM`). - **`crewai-tools[mcp]` `MCPServerAdapter`** — per-request connection to the MCP tool over @@ -96,7 +96,7 @@ Built in `a2a_agent.py::get_agent_card()`. Fields: | id | name | description | tags | examples | |---|---|---|---|---| -| `source_operations` | Source repository operations | Browse and search code; read, create, and modify repository file contents, branches, and commits. | `git, github, source, repositories, files, branches, commits` | "Show the README of kagenti/kagenti", "List the branches of owner/repo", "Create a branch and commit a fix to owner/repo" | +| `source_operations` | Source repository operations | Browse and search code; read, create, and modify repository file contents, branches, and commits. | `git, github, source, repositories, files, branches, commits` | "Show the README of rossoctl/rossoctl", "List the branches of owner/repo", "Create a branch and commit a fix to owner/repo" | | `issue_operations` | Issue & PR tracker operations | Read, search, create, and update issues, comments, sub-issues, and pull requests. | `git, github, issues, pull-requests` | "List open issues in kubernetes/kubernetes", "Open an issue in owner/repo titled …", "Summarise PR #42 in owner/repo" | > The existing `git_issue_agent` card ([`../../analysis/github-agent-card.json`](../../analysis/github-agent-card.json)) @@ -199,15 +199,15 @@ Manifests live under `aiac/demo/agents/github_agent/k8s/`, adapted from the gith `team1` (installer-provided ConfigMaps/secrets assumed present). - **`github-agent-deployment.yaml`** — `ServiceAccount` + `Deployment` + `Service` + `AgentRuntime`: - - **Deployment labels** (on `metadata.labels` **and** pod template): `protocol.kagenti.io/a2a: ""` - in addition to `app.kubernetes.io/name: github-agent`. The `protocol.kagenti.io/a2a` label is + - **Deployment labels** (on `metadata.labels` **and** pod template): `protocol.rossoctl.io/a2a: ""` + in addition to `app.kubernetes.io/name: github-agent`. The `protocol.rossoctl.io/a2a` label is required by the `AgentCardSyncReconciler` (`shouldSyncWorkload` gate): the operator stamps - `kagenti.io/type=agent` automatically via the `AgentRuntime`, but the protocol label must be set + `rossoctl.io/type=agent` automatically via the `AgentRuntime`, but the protocol label must be set in the manifest. Without it, no `AgentCard` CR is auto-created and `analyze_agent` falls back to the default minimal scope. - - Pod labels `kagenti.io/inject: enabled`, `kagenti.io/spire: enabled`, `protocol.kagenti.io/a2a: ""`. + - Pod labels `rossoctl.io/inject: enabled`, `rossoctl.io/spire: enabled`, `protocol.rossoctl.io/a2a: ""`. - Container port `8000`; env `MCP_URL=http://github-tool-mcp:9090/mcp`, - `JWKS_URI=http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/certs`, + `JWKS_URI=http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/certs`, LLM vars, `PORT`, `LOG_LEVEL`; `/shared` `emptyDir` for operator-mounted client creds. - `Service` (ClusterIP) with **two ports** — port order matters because `AgentCardReconciler.getServicePort()` always takes `Ports[0]`: @@ -217,7 +217,7 @@ Manifests live under `aiac/demo/agents/github_agent/k8s/`, adapted from the gith 2. `proxy: 8080 → 8000` (second) — the public/authenticated path through the authbridge reverse proxy; used by A2A clients that carry a valid JWT. - `AgentRuntime{ type: agent, targetRef: this Deployment }` — enrolls the workload (operator applies - `kagenti.io/type=agent`, registers a Keycloak client, injects the AuthBridge sidecar). + `rossoctl.io/type=agent`, registers a Keycloak client, injects the AuthBridge sidecar). - Image `github-agent:latest`, `imagePullPolicy: IfNotPresent` (kind-load; name is a documented knob). - **`configmaps.yaml`** — `authbridge-config` (Keycloak URL/realm/issuer) + `authproxy-routes` with the outbound token-exchange route: @@ -228,7 +228,7 @@ Manifests live under `aiac/demo/agents/github_agent/k8s/`, adapted from the gith ``` - **Prerequisite (reused, not created here):** the existing **production** `github-tool` Deployment/Service (`authbridge/demos/github-issue/k8s/github-tool-deployment.yaml`, Service name `github-tool-mcp`) + - `github-tool-secrets`, a running Kagenti cluster (Keycloak realm `kagenti`, namespace `team1`). + `github-tool-secrets`, a running Rossoctl cluster (Keycloak realm `rossoctl`, namespace `team1`). The sibling UC-1 stub at `demo/tools/github_tool/` (Service `github-tool`) is a separate deployment for AIAC onboarding discovery and is **not** a runtime dependency of this agent. @@ -248,11 +248,11 @@ Service name; exchanged audience (`github-tool`) == tool `AUDIENCE`. 4. (Optional; needs a GitHub PAT + reachable LLM) `GITHUB_TOKEN=… MCP_URL=https://api.githubcopilot.com/mcp/`, send an A2A `message/send` read query and confirm a grounded, tool-cited answer. -**Cluster (HITL — live Kagenti + Keycloak + LLM + tool PAT):** -5. `kind load docker-image github-agent:latest --name kagenti`. +**Cluster (HITL — live Rossoctl + Keycloak + LLM + tool PAT):** +5. `kind load docker-image github-agent:latest --name rossoctl`. 6. Ensure `github-tool` + `github-tool-secrets` exist in `team1`. 7. `kubectl apply -f k8s/configmaps.yaml -f k8s/github-agent-deployment.yaml`. -8. Confirm AuthBridge injection + `kagenti.io/type=agent`; confirm the `AgentCard` CR was +8. Confirm AuthBridge injection + `rossoctl.io/type=agent`; confirm the `AgentCard` CR was auto-created (`kubectl get agentcard -n team1` → `github-agent-deployment-card`, `SYNCED=True`). `kubectl port-forward svc/github-agent 8080:8080 -n team1` (proxy port); send an authenticated A2A message; verify token exchange reaches `github-tool` and an answer returns. diff --git a/aiac/docs/specs/demo/github-tool.md b/aiac/docs/specs/demo/github-tool.md index fa1f8b0e4..fec7b6a68 100644 --- a/aiac/docs/specs/demo/github-tool.md +++ b/aiac/docs/specs/demo/github-tool.md @@ -31,10 +31,10 @@ From `analyze_tool` (`../components/aiac-agent/uc1-service-onboarding.md`): 1. **`classify_service`** resolves identity from the Keycloak client's `client.name` (the operator sets it to `"{namespace}/{workload_name}"`), splits on the first `/` → `namespace` + `workload_name`, - LISTs pods in the namespace, finds the pod owned by `workload_name`, and reads the `kagenti.io/type` + LISTs pods in the namespace, finds the pod owned by `workload_name`, and reads the `rossoctl.io/type` pod label. It **must be `tool`** → routes to `analyze_tool`. 2. **`analyze_tool`** does `read_service(workload_name, namespace)` (the K8s Service named - `workload_name`), **requires the `protocol.kagenti.io/mcp` label** on that Service (a deploy-time + `workload_name`), **requires the `protocol.rossoctl.io/mcp` label** on that Service (a deploy-time prerequisite — the operator does **not** stamp it), takes the Service's **first port**, and POSTs JSON-RPC `tools/list` to `http://{workload_name}.{namespace}.svc.cluster.local:{port}/mcp`. @@ -68,7 +68,7 @@ Phase 1 only discovers and evaluates them. - Scenario fixture (`TOOL_SCOPES`): [`../../../test/integration/scenario.py`](../../../test/integration/scenario.py) - Scenario spec: [`../integration-test/policy-pipeline.md`](../integration-test/policy-pipeline.md) - Sibling agent spec: [`github-agent.md`](github-agent.md) -- Reference deployment: `kagenti-extensions/authbridge/demos/github-issue/k8s/` +- Reference deployment: `rossocortex/authbridge/demos/github-issue/k8s/` --- @@ -207,33 +207,33 @@ ConfigMaps/secrets assumed present), consistent with the agent spec. - **`Deployment`** named `github-tool`. Container port serves `/mcp` (default `9090`). Env `PORT`, `LOG_LEVEL`. Image `github-tool:latest`, `imagePullPolicy: IfNotPresent` (kind-load; name is a documented knob). No GitHub PAT / issuer / JWKS / audience env (unlike the github-issue tool). - - **Pod label `kagenti.io/type: tool`** — this is what `classify_service` reads. Applied by the + - **Pod label `rossoctl.io/type: tool`** — this is what `classify_service` reads. Applied by the operator via the `AgentRuntime` (see below); relying on the operator to stamp it, rather than hand-setting it, keeps it consistent with the operator's own discriminator. - **`Service`** named `github-tool` (ClusterIP), selecting the Deployment's pods. Its **first port** maps to the container's `/mcp` port (e.g. `port: 9090 → targetPort: 9090`). `analyze_tool` uses the Service's **first** port, so keep `/mcp`'s port first. - - **Service label `protocol.kagenti.io/mcp` MUST be present** — a **deploy-time prerequisite** for + - **Service label `protocol.rossoctl.io/mcp` MUST be present** — a **deploy-time prerequisite** for `analyze_tool` (the operator does **not** stamp it; `analyze_tool` returns `502` if absent). Set it - explicitly on the Service metadata (e.g. `protocol.kagenti.io/mcp: "true"`). + explicitly on the Service metadata (e.g. `protocol.rossoctl.io/mcp: "true"`). - **`AgentRuntime{ type: tool, targetRef: { apiVersion: apps/v1, kind: Deployment, name: github-tool } }`** - — enrolls the workload so the kagenti-operator applies `kagenti.io/type=tool` to the pod and + — enrolls the workload so the operator applies `rossoctl.io/type=tool` to the pod and registers a Keycloak client with `client.name = "team1/github-tool"`. Unlike the github-issue demo - (which omits `kagenti.io/type` to skip AuthBridge entirely), this demo **needs** `type: tool` so the - pod carries `kagenti.io/type=tool` for UC-1 `classify_service`. + (which omits `rossoctl.io/type` to skip AuthBridge entirely), this demo **needs** `type: tool` so the + pod carries `rossoctl.io/type=tool` for UC-1 `classify_service`. - **No `configmaps.yaml` needed here** — the tool has no `authbridge-config` / `authproxy-routes` dependency (it neither validates inbound JWTs nor does outbound token exchange in phase 1). The agent spec's `authproxy-routes` still targets the **production** `github-tool-mcp` host and is unrelated to this stand-in. -- **Prerequisite (reused, not created here):** a running Kagenti cluster with the kagenti-operator +- **Prerequisite (reused, not created here):** a running Rossoctl cluster with the operator (Keycloak realm as configured by the installer, namespace `team1`), so the `AgentRuntime` is reconciled into a Keycloak client + pod label. **Wiring invariant:** `AgentRuntime.targetRef.name` == `Deployment` name == `Service` name == -`github-tool`; the `Service` carries the `protocol.kagenti.io/mcp` label and exposes `/mcp` as its first -port; the operator-applied pod label is `kagenti.io/type=tool`; the operator-registered Keycloak +`github-tool`; the `Service` carries the `protocol.rossoctl.io/mcp` label and exposes `/mcp` as its first +port; the operator-applied pod label is `rossoctl.io/type=tool`; the operator-registered Keycloak `client.name` is `team1/github-tool`. --- @@ -254,13 +254,13 @@ port; the operator-applied pod label is `kagenti.io/type=tool`; the operator-reg 3. Confirm each returned tool's `description` is byte-identical to the matching `TOOL_SCOPES` entry in `scenario.py` (e.g. `jq '.result.tools[] | {name, description}'`). -**Cluster (HITL — live Kagenti + Keycloak + operator):** -4. `kind load docker-image github-tool:latest --name kagenti`. +**Cluster (HITL — live Rossoctl + Keycloak + operator):** +4. `kind load docker-image github-tool:latest --name rossoctl`. 5. `kubectl apply -f k8s/github-tool-deployment.yaml`. 6. Confirm the operator applied the pod label: `kubectl get pod -l app=github-tool -n team1 - -o jsonpath='{.items[0].metadata.labels.kagenti\.io/type}'` → `tool`. + -o jsonpath='{.items[0].metadata.labels.rossoctl\.io/type}'` → `tool`. 7. Confirm the Service carries the MCP label: `kubectl get svc github-tool -n team1 - -o jsonpath='{.metadata.labels.protocol\.kagenti\.io/mcp}'` → present. + -o jsonpath='{.metadata.labels.protocol\.rossoctl\.io/mcp}'` → present. 8. Confirm the operator registered a Keycloak client with `client.name = "team1/github-tool"` (via the Keycloak admin API / IdP `Configuration` library). 9. From inside the cluster (or via `kubectl port-forward svc/github-tool 9090:9090 -n team1`), POST diff --git a/aiac/docs/specs/integration-test/policy-pipeline.md b/aiac/docs/specs/integration-test/policy-pipeline.md index 01bc916ce..fde5e4685 100644 --- a/aiac/docs/specs/integration-test/policy-pipeline.md +++ b/aiac/docs/specs/integration-test/policy-pipeline.md @@ -378,7 +378,7 @@ The descriptions are **generic and keyword-free** — they describe what each en carry no policy grant ("Resolves to…") and no owning-client naming, and stay within Keycloak's 255-char cap so they are written verbatim (no shortened renderings). Client `type` is **not** inferred from description prose: the test provisions each client's `client.type` attribute (the type UC1 -discovers from the agent card / `kagenti.io/type` label) as a plain string `"Agent"` / `"Tool"`, so +discovers from the agent card / `rossoctl.io/type` label) as a plain string `"Agent"` / `"Tool"`, so `Service` type resolution ([../../../src/aiac/idp/configuration/models.py:79-87](../../../src/aiac/idp/configuration/models.py#L79-L87)) tags each client from the attribute without touching the TEMP description-keyword fallback. diff --git a/aiac/docs/specs/integration-test/uc1-onboarding-pipeline.md b/aiac/docs/specs/integration-test/uc1-onboarding-pipeline.md index bb2fbf371..7132f6060 100644 --- a/aiac/docs/specs/integration-test/uc1-onboarding-pipeline.md +++ b/aiac/docs/specs/integration-test/uc1-onboarding-pipeline.md @@ -36,7 +36,7 @@ verification query, adapted from `5.3`'s `probe.rego` to match against **full di A `@pytest.mark.integration` test that validates the **phase-1 deliverable** ([../../gh-issues/sub-issue-phase-1.md](../../gh-issues/sub-issue-phase-1.md)) and confirms the runnable -demo: it deploys the real **`github-agent`** and a simplified **`github-tool`** to a live Kagenti/Kind +demo: it deploys the real **`github-agent`** and a simplified **`github-tool`** to a live Rossoctl/Kind cluster, drives the **real UC-1 Service Onboarding agent** (`onboard_service` via the Controller's HTTP trigger) for each, and then **asserts** the generated Rego decides correctly by running the standalone `opa eval` binary as its verification oracle. @@ -44,7 +44,7 @@ trigger) for each, and then **asserts** the generated Rego decides correctly by Phase-1 is explicit that **live enforcement / live traffic is out of scope** — correctness is shown by **evaluating the generated rules**, not by routing real requests. So this test is *Deploy + discover + evaluate*: the agent and tool are really deployed and really discovered by UC-1 (classify from the -`kagenti.io/type` label, read the AgentCard, read the MCP `tools/list`, provision roles/scopes into +`rossoctl.io/type` label, read the AgentCard, read the MCP `tools/list`, provision roles/scopes into Keycloak, model access, emit Rego), but **no A2A message is ever sent through the agent**. The generated Rego is the **artifact under test** — the LLM/PCE that produced it might be wrong — so the @@ -52,7 +52,7 @@ test never trusts it. Expected verdicts are **computed from** the `scenario_uc1. intended policy), and the real Rego is asserted to admit/deny each scenario-derived request as the truth table requires. A mismatch fails the test and names the exact cell. -Because it needs a live Kagenti cluster + operator + Keycloak + a real LLM, it is `@pytest.mark.integration` +Because it needs a live Rossoctl cluster + operator + Keycloak + a real LLM, it is `@pytest.mark.integration` and stays out of the default unit run (`-m "not integration"`); it additionally `pytest.skip`s when no `opa` binary is found. @@ -80,9 +80,9 @@ asserts the truth table against **each** variant's Rego (step 7). Steps 1–6 de 0. **Point the demo namespace at the dedicated realm (test fixture).** Before deploying workloads, set `KEYCLOAK_REALM=` in the demo namespace's **`authbridge-config`** ConfigMap. The - kagenti-operator reads the realm per-namespace from this key and **preserves an admin/CI-set value** + operator reads the realm per-namespace from this key and **preserves an admin/CI-set value** (operator issue #433), so the operator registers *this* namespace's clients into the test realm with - **no operator restart or cluster-wide change**. (Default without this is `kagenti`.) + **no operator restart or cluster-wide change**. (Default without this is `rossoctl`.) 1. **Provision the realm's users + realm roles (test fixture).** UC-1 does **not** create users or realm roles, so the fixture provisions them via **`python-keycloak` `KeycloakAdmin`** into the dedicated test realm (`AIAC_TEST_REALM`), **before** onboarding (the Service Policy Builder reads the full realm-role @@ -95,9 +95,9 @@ asserts the truth table against **each** variant's Rego (step 7). Steps 1–6 de 2. **Deploy the demo workloads.** `kubectl apply` the simplified **`github-tool`** ([../demo/github-tool.md](../demo/github-tool.md)) and the real **`github-agent`** ([../demo/github-agent.md](../demo/github-agent.md)) into the demo namespace. Wait until: pods Ready; - the kagenti-operator has **registered a Keycloak client** for each (with `client.name = - "{namespace}/{workload}"`) and applied the `kagenti.io/type` pod label (`tool`/`agent`); the - `github-agent` **AgentCard CR** is present; the tool **Service** carries the `protocol.kagenti.io/mcp` + the operator has **registered a Keycloak client** for each (with `client.name = + "{namespace}/{workload}"`) and applied the `rossoctl.io/type` pod label (`tool`/`agent`); the + `github-agent` **AgentCard CR** is present; the tool **Service** carries the `protocol.rossoctl.io/mcp` label and answers `tools/list`. 3. **Onboard the tool, then the agent (real UC-1), against each variant's AIAC stack.** Order matters — @@ -254,7 +254,7 @@ with; the generic descriptions are not part of this triad): | Variable | Purpose | Default | |----------|---------|---------| -| `KUBECONFIG` | Kubeconfig for the live Kagenti/Kind cluster | — (required) | +| `KUBECONFIG` | Kubeconfig for the live Rossoctl/Kind cluster | — (required) | | `AIAC_DEMO_NAMESPACE` | Namespace the demo workloads deploy into | `team1` | | `KEYCLOAK_URL` | External Keycloak base URL | — (required) | | `KEYCLOAK_ADMIN_REALM` | Realm the admin creds live in | `master` | @@ -275,7 +275,7 @@ with; the generic descriptions are not part of this triad): ## Runbook -Runnable only against a live Kagenti/Kind cluster (operator + Keycloak + SPIRE) **configured to register +Runnable only against a live Rossoctl/Kind cluster (operator + Keycloak + SPIRE) **configured to register clients into `AIAC_TEST_REALM`**, with the two AIAC variant stacks deployable, a real LLM, the demo agent (GA-1…9) and simplified tool images built + kind-loaded, and an `opa` binary on `PATH` (or `$OPA_BIN`). @@ -297,7 +297,7 @@ optionally inspect the provisioned Keycloak realm and the discovered scopes. ## Testing Decisions -- **Highest seam available, verified by a real oracle.** Real deployed workloads + real kagenti-operator +- **Highest seam available, verified by a real oracle.** Real deployed workloads + real operator + real UC-1 onboarding + real PRB/PCE + real Keycloak + real LLM. The test drives the pipeline through its production trigger (`POST /apply/service/{id}`) and verifies the real filesystem Rego with the standalone `opa eval` binary. A good test here asserts only **external behavior** — the *decisions* the @@ -306,7 +306,7 @@ optionally inspect the provisioned Keycloak realm and the discovered scopes. `scenario_uc1.py`, not from the Rego. A wrong role→scope mapping fails the test at the exact cell. - **Deploy + discover + evaluate, no live traffic.** Per phase-1, enforcement/token-exchange/live A2A is out of scope; correctness is shown by evaluating the generated rules. The agent pod need only exist - (labelled `kagenti.io/type=agent`, AgentCard present); the simplified tool need only answer `tools/list` + (labelled `rossoctl.io/type=agent`, AgentCard present); the simplified tool need only answer `tools/list` — neither is driven with real requests. - **In-cluster AIAC for MCP reachability.** UC-1's `analyze_tool` posts `tools/list` to a cluster-internal DNS name, so the pipeline runs in-cluster (triggered over HTTP) rather than in-process @@ -383,16 +383,16 @@ Tracking issue for this test: `testing/5.4-uc1-onboarding-integration-test.md`. - Demo `github-agent` implementation — `demo/GA-1…GA-9` (deployable agent + AgentCard). - UC-1 Service Onboarding — `agent/service-onboarding/3.6-service-onboarding-orchestrator.md` (**done**). - The PRB / PCE / OPA-writer / Policy-Store prerequisites shared with `5.3`. -- A live Kagenti/Kind cluster + operator (registers clients into `AIAC_TEST_REALM` via the demo +- A live Rossoctl/Kind cluster + operator (registers clients into `AIAC_TEST_REALM` via the demo namespace's `authbridge-config` `KEYCLOAK_REALM`, set by the fixture — per-namespace, confirmed against - the operator source); the `protocol.kagenti.io/mcp` Service label applied at deploy time - (`../../gh-issues/kagenti-operator-mcp-label-stamping.md`); an `opa` binary at test time. + the operator source); the `protocol.rossoctl.io/mcp` Service label applied at deploy time + (`../../gh-issues/operator-mcp-label-stamping.md`); an `opa` binary at test time. ## Scenario inputs These are **functional** inputs — the PRB reads the descriptions and the `policy.md` to produce the role→scope mappings. The entity/role/scope descriptions are **generic and keyword-free**; client `type` -is set by UC-1 from the `kagenti.io/type` label (not description prose). +is set by UC-1 from the `rossoctl.io/type` label (not description prose). ### Discovered entities (what UC-1 provisions) diff --git a/authbridge/CLAUDE.md b/authbridge/CLAUDE.md index 3c17c8853..d79a4bb8f 100644 --- a/authbridge/CLAUDE.md +++ b/authbridge/CLAUDE.md @@ -2,7 +2,7 @@ This file provides context for Claude (AI assistant) when working with the `AuthBridge` codebase. For repo-level context (CI/CD, cross-component relationships), see [`../CLAUDE.md`](../CLAUDE.md). -The sidecar injection webhook lives in [kagenti-operator](https://github.com/kagenti/kagenti-operator). +The sidecar injection webhook lives in [operator](https://github.com/rossoctl/operator). ## Binaries @@ -140,7 +140,7 @@ wants to register. - The operator-supplied env vars (`KEYCLOAK_URL`, `KEYCLOAK_REALM`, `TOKEN_URL`, `ISSUER`, `DEFAULT_OUTBOUND_POLICY`, `CLIENT_ID`) are consumed by the default `authbridge-combined.yaml` via `${VAR}` expansion — they land inside the appropriate plugin's `config:` block rather than a top-level section. - `jwt-validation` derives `jwks_url` from `issuer` when omitted (appends `/protocol/openid-connect/certs`). - `token-exchange` derives `token_url` from `keycloak_url + keycloak_realm` when omitted (Keycloak convention). -- Credential files: the **kagenti-operator** registers each workload with Keycloak and creates a Secret containing `client-id.txt` + `client-secret.txt`; the operator's webhook mounts that Secret at `/shared/client-id.txt` and `/shared/client-secret.txt` in containers that share the `shared-data` volume. SPIRE-issued credentials are sourced in-process via the `spiffe.Provider` (built from the top-level `spiffe:` block in `authbridge-runtime`) — authbridge's hot path reads X.509 SVIDs from an in-memory `spiffe.X509Source` (no per-handshake file I/O), and `token-exchange` consumes a JWT-SVID from the injected Provider via `plugins.BuildWithSPIFFE`. The Provider also mirrors `/opt/jwt_svid.token`, `/opt/svid.pem`, `/opt/svid_key.pem`, and `/opt/svid_bundle.pem` for external readers (e2e probes, debugging, future Envoy filesystem SDS). The `spiffe-helper` binary is no longer bundled in any combined image, and the `SPIRE_ENABLED` env var no longer gates anything — presence/absence of the `spiffe:` block in YAML drives behavior. `jwt-validation` reads the audience from `/shared/client-id.txt` via `audience_file`; `token-exchange` reads client credentials via `client_id_file` / `client_secret_file`. Each plugin attempts a synchronous read at Configure time and falls back to a background poll from its `Init` goroutine if the file isn't yet readable. The legacy in-pod `client-registration` sidecar has been removed entirely; the `kagenti.io/client-registration-inject: "true"` label is **no longer functional** — the operator's `ClientRegistrationReconciler` still treats it as a "skip operator-managed registration" signal (`SkipReason` in `kagenti-operator/internal/clientreg/names.go:58`), but the legacy sidecar that the label deferred to is gone. Setting it today silently breaks registration; do not add it to new manifests. +- Credential files: the **operator** registers each workload with Keycloak and creates a Secret containing `client-id.txt` + `client-secret.txt`; the operator's webhook mounts that Secret at `/shared/client-id.txt` and `/shared/client-secret.txt` in containers that share the `shared-data` volume. SPIRE-issued credentials are sourced in-process via the `spiffe.Provider` (built from the top-level `spiffe:` block in `authbridge-runtime`) — authbridge's hot path reads X.509 SVIDs from an in-memory `spiffe.X509Source` (no per-handshake file I/O), and `token-exchange` consumes a JWT-SVID from the injected Provider via `plugins.BuildWithSPIFFE`. The Provider also mirrors `/opt/jwt_svid.token`, `/opt/svid.pem`, `/opt/svid_key.pem`, and `/opt/svid_bundle.pem` for external readers (e2e probes, debugging, future Envoy filesystem SDS). The `spiffe-helper` binary is no longer bundled in any combined image, and the `SPIRE_ENABLED` env var no longer gates anything — presence/absence of the `spiffe:` block in YAML drives behavior. `jwt-validation` reads the audience from `/shared/client-id.txt` via `audience_file`; `token-exchange` reads client credentials via `client_id_file` / `client_secret_file`. Each plugin attempts a synchronous read at Configure time and falls back to a background poll from its `Init` goroutine if the file isn't yet readable. The legacy in-pod `client-registration` sidecar has been removed entirely; the `rossoctl.io/client-registration-inject: "true"` label is **no longer functional** — the operator's `ClientRegistrationReconciler` still treats it as a "skip operator-managed registration" signal (`SkipReason` in `operator/internal/clientreg/names.go:58`), but the legacy sidecar that the label deferred to is gone. Setting it today silently breaks registration; do not add it to new manifests. - Outbound route config: `token-exchange` reads `/etc/authproxy/routes.yaml` by default (path is per-plugin, configured via `routes.file` in its config block); inline rules can be declared under `routes.rules`. - Outbound `default_policy`: `passthrough` (default) or `exchange`, configured per-plugin (no top-level `DEFAULT_OUTBOUND_POLICY` field anymore; the env var is still expanded into the plugin config by `authbridge-combined.yaml`). @@ -201,14 +201,14 @@ Declarative Keycloak synchronization tool that maintains client scope mappings b ### Envoy Configuration -Envoy config lives in the `envoy-config` ConfigMap rendered by the [kagenti Helm chart](https://github.com/kagenti/kagenti) at install time (template: `charts/kagenti/templates/agent-namespaces.yaml` / `authbridge-template-configmaps.yaml`). Key listeners: `outbound_listener` (15123), `inbound_listener` (15124). Inbound listener injects `x-authbridge-direction: inbound` header. Both use ext_proc cluster pointing to the authbridge binary on localhost:9090. +Envoy config lives in the `envoy-config` ConfigMap rendered by the [rossoctl Helm chart](https://github.com/rossoctl/rossoctl) at install time (template: `charts/rossoctl/templates/agent-namespaces.yaml` / `authbridge-template-configmaps.yaml`). Key listeners: `outbound_listener` (15123), `inbound_listener` (15124). Inbound listener injects `x-authbridge-direction: inbound` header. Both use ext_proc cluster pointing to the authbridge binary on localhost:9090. ## Demo Scenarios The `demos/` directory contains the following scenarios (see `demos/README.md` for a recommended learning path): - **weather-agent/** -- Getting-started demo: inbound JWT validation with outbound passthrough. Simplest way to see AuthBridge in action (UI deployment). `demo-ui-advanced.md` extends this with outbound token exchange and tool-side AuthBridge; `demo-with-abctl.md` is a plugin-pipeline tooling walkthrough. -- **webhook/** -- Shows how to use the webhook (now part of [kagenti-operator](https://github.com/kagenti/kagenti-operator)) to automatically inject AuthBridge sidecars. Recommended starting point for webhook-based deployments. +- **webhook/** -- Shows how to use the webhook (now part of [operator](https://github.com/rossoctl/operator)) to automatically inject AuthBridge sidecars. Recommended starting point for webhook-based deployments. - **github-issue/** -- External API integration (GitHub) with inbound validation, outbound token exchange, and scope-based access control. Available as UI or manual deployment. - **token-exchange-routes/** -- Configuration reference for the `authproxy-routes` ConfigMap. Covers single-target (one route) and multi-target (one agent → many tools) patterns. Pairs with one of the deployment demos for a full stack. - **mcp-parser/** -- Configuration reference for enabling the outbound `mcp-parser` plugin. @@ -224,19 +224,19 @@ There are **two** setup scripts for different demo scenarios: **Common Keycloak defaults across all scripts:** - URL: `http://keycloak.localtest.me:8080` -- Realm: `kagenti` +- Realm: `rossoctl` - Admin: `admin` / `admin` **Note:** All scripts share the same helper function patterns (`get_or_create_realm`, `get_or_create_client`, `get_or_create_client_scope`, etc.) and are idempotent. ## Required ConfigMaps for Webhook Injection -When the webhook injects sidecars (via [kagenti-operator](https://github.com/kagenti/kagenti-operator)), these ConfigMaps must exist in the target namespace. The kagenti Helm chart's `agent-namespaces.yaml` and `authbridge-template-configmaps.yaml` templates render them; the operator copies them into agent namespaces that don't already have them: +When the webhook injects sidecars (via [operator](https://github.com/rossoctl/operator)), these ConfigMaps must exist in the target namespace. The rossoctl Helm chart's `agent-namespaces.yaml` and `authbridge-template-configmaps.yaml` templates render them; the operator copies them into agent namespaces that don't already have them: | Resource | Kind | Consumer | Key Fields | |----------|------|----------|------------| | `authbridge-config` | ConfigMap | authbridge | `KEYCLOAK_URL`, `KEYCLOAK_REALM`, `PLATFORM_CLIENT_IDS` (optional), `TOKEN_URL` (optional, derived), `ISSUER` (optional, derived or explicit), `DEFAULT_OUTBOUND_POLICY` (optional). Inbound audience validation uses `CLIENT_ID` from `/shared/client-id.txt`. Target audience and scopes are configured per-route in `authproxy-routes`. | -| `keycloak-admin-secret` | Secret | kagenti-operator (ClientRegistrationReconciler) | `KEYCLOAK_ADMIN_USERNAME`, `KEYCLOAK_ADMIN_PASSWORD` | +| `keycloak-admin-secret` | Secret | operator (ClientRegistrationReconciler) | `KEYCLOAK_ADMIN_USERNAME`, `KEYCLOAK_ADMIN_PASSWORD` | | `authproxy-routes` | ConfigMap (optional) | authbridge | `routes.yaml` with per-host token exchange rules | | `spiffe-helper-config` | ConfigMap (legacy, unused by authbridge) | (none — retained only for compatibility with older deployments) | Previously held `helper.conf` for the bundled `spiffe-helper` binary. Authbridge now drives SPIRE configuration via the top-level `spiffe:` block in `authbridge-runtime` and no longer reads this ConfigMap. | | `envoy-config` | ConfigMap | Envoy (inside the `authbridge-envoy` combined image, envoy-sidecar mode only) | `envoy.yaml` (full Envoy configuration) | @@ -352,7 +352,7 @@ strict inbound rejects it). Mixed-mode deployments need both ends compatible — both strict, both permissive, or one strict + the other permissive on inbound only. -The kagenti-operator's AgentRuntime CR's `Spec.MTLSMode` flows +The operator's AgentRuntime CR's `Spec.MTLSMode` flows through to a per-agent rendered envoy-config with the matching TLS blocks (operator companion PR). The `authbridge/demos/mtls/` envoy-sidecar variant (`make demo-mtls-envoy*`) ships a hand-crafted @@ -367,11 +367,11 @@ without needing a CR. # Build the proxy-init iptables init container (envoy-sidecar + proxy-sidecar enforce-redirect modes) cd authbridge/proxy-init make docker-build-init -make load-image # Uses KIND_CLUSTER_NAME env var (default: kagenti) +make load-image # Uses KIND_CLUSTER_NAME env var (default: rossoctl) # Build the combined sidecar images from the authbridge/ context. # Pick whichever you need; the operator selects the image per workload -# from the resolved AuthBridge mode (see kagenti-operator#361). +# from the resolved AuthBridge mode (see operator#361). cd .. podman build -f cmd/authbridge-proxy/Dockerfile -t authbridge:latest . # proxy-sidecar (default) podman build -f cmd/authbridge-envoy/Dockerfile -t authbridge-envoy:latest . # envoy-sidecar @@ -379,12 +379,12 @@ podman build -f cmd/authbridge-envoy/Dockerfile -t authbridge-envoy:latest . # e podman build -f cmd/authbridge-proxy/Dockerfile \ --build-arg GO_BUILD_TAGS="exclude_plugin_a2aparser,exclude_plugin_ibac,exclude_plugin_inferenceparser,exclude_plugin_mcpparser,exclude_plugin_opa,exclude_plugin_sparc,exclude_plugin_tokenbroker" \ -t authbridge-lite:latest . -kind load docker-image authbridge:latest --name kagenti -kind load docker-image authbridge-envoy:latest --name kagenti -kind load docker-image authbridge-lite:latest --name kagenti +kind load docker-image authbridge:latest --name rossoctl +kind load docker-image authbridge-envoy:latest --name rossoctl +kind load docker-image authbridge-lite:latest --name rossoctl ``` -For the repo-level "build everything" path, the root `local-build-and-test.sh` orchestrates all four images plus the kagenti-side `spiffe-idp-setup`. +For the repo-level "build everything" path, the root `local-build-and-test.sh` orchestrates all four images plus the rossoctl-side `spiffe-idp-setup`. ### Full demo with webhook injection @@ -524,7 +524,7 @@ See [`docs/framework-architecture.md`](docs/framework-architecture.md#9-config-h - `python-keycloak` library for all Keycloak admin API calls - `PyJWT` for JWT decoding (signature verification disabled -- uses `verify_signature: False`) - Idempotent: all `get_or_create_*` helper functions check existence before creating -- UID/GID 1000 in Dockerfile **must match** the `runAsUser`/`runAsGroup` values set by the operator's webhook when injecting the client-registration container (see [kagenti-operator](https://github.com/kagenti/kagenti-operator)) +- UID/GID 1000 in Dockerfile **must match** the `runAsUser`/`runAsGroup` values set by the operator's webhook when injecting the client-registration container (see [operator](https://github.com/rossoctl/operator)) ### Shell (init-iptables.sh) - `set -e` (exit on error) @@ -539,7 +539,7 @@ See [`docs/framework-architecture.md`](docs/framework-architecture.md#9-config-h - Test by rebuilding the affected combined image (e.g., `cd authbridge && podman build -f cmd/authbridge-envoy/Dockerfile -t authbridge-envoy:latest .` then `kind load docker-image - authbridge-envoy:latest --name kagenti`). + authbridge-envoy:latest --name rossoctl`). ### Modifying Inbound JWT Validation - Edit `authlib/validation/` -- the JWKS-backed JWT verifier @@ -564,8 +564,8 @@ See [`docs/framework-architecture.md`](docs/framework-architecture.md#9-config-h - All scripts use `python-keycloak` library (KeycloakAdmin class) ### Changing Envoy Configuration -- Edit the `envoy.yaml` template in the [kagenti Helm chart](https://github.com/kagenti/kagenti) - (`charts/kagenti/templates/agent-namespaces.yaml` or +- Edit the `envoy.yaml` template in the [rossoctl Helm chart](https://github.com/rossoctl/rossoctl) + (`charts/rossoctl/templates/agent-namespaces.yaml` or `authbridge-template-configmaps.yaml`) and `helm upgrade` - Key listener/cluster names: `outbound_listener`, `inbound_listener`, `original_destination`, `ext_proc_cluster` - After changes, restart the affected pods so they pick up the new ConfigMap content @@ -580,7 +580,7 @@ See [`docs/framework-architecture.md`](docs/framework-architecture.md#9-config-h 4. **TLS passthrough is one-way**: Outbound HTTPS traffic passes through Envoy without token exchange via the TLS passthrough filter chain. Only plaintext HTTP outbound traffic reaches authbridge. With the default outbound policy of `"passthrough"`, even plaintext HTTP traffic is forwarded unchanged unless it matches an explicit route in `authproxy-routes`. -5. **Admin credentials in ConfigMap**: the kagenti Helm chart's +5. **Admin credentials in ConfigMap**: the rossoctl Helm chart's `agent-namespaces.yaml` template stores Keycloak admin credentials in `authbridge-config` (a ConfigMap, not a Secret). This is for demo / dev clusters only — production should use a Kubernetes diff --git a/authbridge/README.md b/authbridge/README.md index 22b8262aa..0b078e72a 100644 --- a/authbridge/README.md +++ b/authbridge/README.md @@ -1,6 +1,6 @@ # AuthBridge -AuthBridge provides **secure, transparent token management** for Kubernetes workloads. The shared library is at [`authlib/`](./authlib/); the mode-specific binaries (proxy-sidecar default, envoy-sidecar, lite) live under [`cmd/`](./cmd/). Keycloak client registration is handled by the [kagenti-operator](https://github.com/kagenti/kagenti-operator)'s `ClientRegistrationReconciler` (no in-pod registration sidecar). Together with [SPIFFE/SPIRE](https://spiffe.io), this enables zero-trust authentication flows. +AuthBridge provides **secure, transparent token management** for Kubernetes workloads. The shared library is at [`authlib/`](./authlib/); the mode-specific binaries (proxy-sidecar default, envoy-sidecar, lite) live under [`cmd/`](./cmd/). Keycloak client registration is handled by the [operator](https://github.com/rossoctl/operator)'s `ClientRegistrationReconciler` (no in-pod registration sidecar). Together with [SPIFFE/SPIRE](https://spiffe.io), this enables zero-trust authentication flows. > **📘 Looking to run the demo?** See the [Weather Agent](./demos/weather-agent/demo-ui.md) or [GitHub Issue Agent](./demos/github-issue/demo.md) demos for step-by-step instructions, and [Token-Exchange Routes](./demos/token-exchange-routes/README.md) for route configuration. @@ -20,13 +20,13 @@ The [`cmd/authbridge/`](./cmd/authbridge/) directory contains a unified binary t | `envoy-sidecar` | `authbridge-envoy` | Transparent interception via iptables | Envoy intercepts all traffic, delegates auth to authbridge via ext_proc gRPC | | `lite` | `authbridge-lite` | The `authbridge-proxy` binary built with `exclude_plugin_*` tags (auth-only: jwt-validation + token-exchange) | For size-constrained deployments that don't need protocol-aware session events | -The kagenti-operator resolves the mode per workload from `AgentRuntime.Spec.AuthBridgeMode` → namespace ConfigMap → deprecated `kagenti.io/authbridge-mode` annotation → cluster default (`proxy-sidecar`). See kagenti-operator#361. +The operator resolves the mode per workload from `AgentRuntime.Spec.AuthBridgeMode` → namespace ConfigMap → deprecated `rossoctl.io/authbridge-mode` annotation → cluster default (`proxy-sidecar`). See operator#361. The shared auth library at [`authlib/`](./authlib/) contains the building blocks (JWT validation, token exchange, caching, routing) with no protocol dependencies. See [`authlib/README.md`](./authlib/README.md) for package reference. ## Architecture (Operator-Injected) -The following describes the operator-injected sidecar deployment. After kagenti-extensions#411 each mode is served by its own combined image (one container per pod, with `spiffe-helper` bundled inside and gated by `SPIRE_ENABLED`). The legacy `authbridge-unified`, `authbridge-light`, `envoy-with-processor`, and standalone `client-registration` / `spiffe-helper` sidecars are gone. +The following describes the operator-injected sidecar deployment. After rossocortex#411 each mode is served by its own combined image (one container per pod, with `spiffe-helper` bundled inside and gated by `SPIRE_ENABLED`). The legacy `authbridge-unified`, `authbridge-light`, `envoy-with-processor`, and standalone `client-registration` / `spiffe-helper` sidecars are gone. ### What AuthBridge Does @@ -77,8 +77,8 @@ AuthBridge solves the challenge of **secure service-to-service authentication** │ └─────────────────────────────────────────────────────────────────┘ │ └───────────────────────────────────────────────────────────────────────┘ ▲ - │ Out-of-band: kagenti-operator's ClientRegistrationReconciler - │ creates the Keycloak client + a kagenti-keycloak-client-credentials + │ Out-of-band: operator's ClientRegistrationReconciler + │ creates the Keycloak client + a rossoctl-keycloak-client-credentials │ Secret. The webhook mounts that Secret into the AuthBridge sidecar │ at /shared/client-{id,secret}.txt — no in-pod registration sidecar. │ @@ -108,7 +108,7 @@ flowchart TB end end - subgraph Operator["kagenti-operator (kagenti-system)"] + subgraph Operator["operator (rossoctl-system)"] ClientReg["ClientRegistration
Reconciler"] end @@ -149,7 +149,7 @@ flowchart TB ### Workload Pod -After kagenti-extensions#411 a workload pod has the application +After rossocortex#411 a workload pod has the application container plus a single combined AuthBridge sidecar. In envoy-sidecar mode it also has a one-shot `proxy-init` init container; in proxy-sidecar mode (the cluster default) it does @@ -344,16 +344,16 @@ sequenceDiagram ### Quick Setup -The easiest way to get all prerequisites is to use the [Kagenti Ansible installer](https://github.com/kagenti/kagenti/blob/main/docs/install.md#ansible-based-installer-recommended). +The easiest way to get all prerequisites is to use the [Rossoctl Ansible installer](https://github.com/rossoctl/rossoctl/blob/main/docs/install.md#ansible-based-installer-recommended). ## Getting Started ### Demos -- **[Weather Agent Demo](./demos/weather-agent/demo-ui.md)** - Recommended starting demo: shows how the [kagenti-operator](https://github.com/kagenti/kagenti-operator) webhook automatically injects the combined AuthBridge sidecar, with inbound JWT validation and outbound passthrough +- **[Weather Agent Demo](./demos/weather-agent/demo-ui.md)** - Recommended starting demo: shows how the [operator](https://github.com/rossoctl/operator) webhook automatically injects the combined AuthBridge sidecar, with inbound JWT validation and outbound passthrough - **[GitHub Issue Agent Demo](./demos/github-issue/demo.md)** - End-to-end demo with the real GitHub Issue Agent and GitHub MCP Tool, showing transparent token exchange via AuthBridge - [Manual deployment](./demos/github-issue/demo-manual.md) — deploy everything via `kubectl` and YAML manifests - - [UI deployment](./demos/github-issue/demo-ui.md) — import agent and tool via the Kagenti dashboard + - [UI deployment](./demos/github-issue/demo-ui.md) — import agent and tool via the Rossoctl dashboard - **[Token-Exchange Routes](./demos/token-exchange-routes/README.md)** - Configuration reference for the `authproxy-routes` ConfigMap; covers single-target (one route) and multi-target (one agent → many tools) patterns All demos cover configuring Keycloak, deploying, and testing. @@ -432,7 +432,7 @@ To make a plugin excludable: package main -import _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/" +import _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/" ``` 2. Remove the corresponding `_ "...plugins/"` import from that binary's `main.go`. @@ -452,10 +452,10 @@ plugin package from being imported and compiled into the binary. - [proxy-init](proxy-init/README.md) — iptables init container (envoy-sidecar mode only) - [docs/](docs/) — framework architecture and plugin author references -Keycloak client registration is handled by the [kagenti-operator](https://github.com/kagenti/kagenti-operator)'s `ClientRegistrationReconciler`, not by an in-pod sidecar. +Keycloak client registration is handled by the [operator](https://github.com/rossoctl/operator)'s `ClientRegistrationReconciler`, not by an in-pod sidecar. ## References -- [Kagenti Installation](https://github.com/kagenti/kagenti/blob/main/docs/install.md) +- [Rossoctl Installation](https://github.com/rossoctl/rossoctl/blob/main/docs/install.md) - [SPIRE Documentation](https://spiffe.io/docs/latest/) - [OAuth 2.0 Token Exchange (RFC 8693)](https://www.rfc-editor.org/rfc/rfc8693) diff --git a/authbridge/authlib/README.md b/authbridge/authlib/README.md index 4576fa237..4583d8a04 100644 --- a/authbridge/authlib/README.md +++ b/authbridge/authlib/README.md @@ -36,8 +36,8 @@ Plugins own their own configuration and construct any `auth.Auth` they need inte ```go import ( - "github.com/kagenti/kagenti-extensions/authbridge/authlib/config" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins" + "github.com/rossoctl/rossocortex/authbridge/authlib/config" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins" ) cfg, _ := config.Load("config.yaml") @@ -58,7 +58,7 @@ For direct use of the `auth/` composition layer (outside of plugins), see `auth/ ## Go Module ``` -module github.com/kagenti/kagenti-extensions/authbridge/authlib +module github.com/rossoctl/rossocortex/authbridge/authlib ``` Direct dependencies: `lestrrat-go/jwx/v2`, `gobwas/glob`, `gopkg.in/yaml.v3`. No gRPC or Envoy deps. diff --git a/authbridge/authlib/auth/auth.go b/authbridge/authlib/auth/auth.go index 503e12009..b1e0aa036 100644 --- a/authbridge/authlib/auth/auth.go +++ b/authbridge/authlib/auth/auth.go @@ -10,11 +10,11 @@ import ( "sync/atomic" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/bypass" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/jwtvalidation/validation" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/tokenexchange/cache" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/tokenexchange/exchange" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/routing" + "github.com/rossoctl/rossocortex/authbridge/authlib/bypass" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/jwtvalidation/validation" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/tokenexchange/cache" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/tokenexchange/exchange" + "github.com/rossoctl/rossocortex/authbridge/authlib/routing" ) // IdentityConfig holds the agent's identity for audience validation and token exchange. diff --git a/authbridge/authlib/auth/auth_test.go b/authbridge/authlib/auth/auth_test.go index ae20f5447..d84d20165 100644 --- a/authbridge/authlib/auth/auth_test.go +++ b/authbridge/authlib/auth/auth_test.go @@ -10,11 +10,11 @@ import ( "testing" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/bypass" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/jwtvalidation/validation" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/tokenexchange/cache" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/tokenexchange/exchange" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/routing" + "github.com/rossoctl/rossocortex/authbridge/authlib/bypass" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/jwtvalidation/validation" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/tokenexchange/cache" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/tokenexchange/exchange" + "github.com/rossoctl/rossocortex/authbridge/authlib/routing" ) // mockVerifier captures the audiences arg and returns configured claims/error. diff --git a/authbridge/authlib/auth/result.go b/authbridge/authlib/auth/result.go index 673351572..b4afa2669 100644 --- a/authbridge/authlib/auth/result.go +++ b/authbridge/authlib/auth/result.go @@ -3,7 +3,7 @@ package auth import ( - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/jwtvalidation/validation" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/jwtvalidation/validation" ) // Inbound actions. diff --git a/authbridge/authlib/config/config.go b/authbridge/authlib/config/config.go index 1a83d91c4..511326ecb 100644 --- a/authbridge/authlib/config/config.go +++ b/authbridge/authlib/config/config.go @@ -9,7 +9,7 @@ import ( "os" "strings" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" "gopkg.in/yaml.v3" ) @@ -397,7 +397,7 @@ type ListenerConfig struct { // // Patterns use `.`-delimited glob semantics (same library as // `authproxy-routes`): "otel-collector*" matches the short - // service name, "otel-collector.kagenti-system.svc.cluster.local" + // service name, "otel-collector.rossoctl-system.svc.cluster.local" // matches the FQDN, "*-collector" matches any single-label name // ending in -collector. Port is stripped before matching, so // patterns must NOT include `:port`. @@ -477,7 +477,7 @@ func Load(path string) (*Config, error) { // Default stats server address if cfg.Stats.StatsAddress == "" { // Note that we default to an open port, not localhost 127.0.0.1:9093, - // because the Kagenti UI needs to see this. (If there are concerns + // because the Rossoctl UI needs to see this. (If there are concerns // about the data exposed, use TLS or redact fields.) cfg.Stats.StatsAddress = ":9093" } diff --git a/authbridge/authlib/config/config_test.go b/authbridge/authlib/config/config_test.go index 71b0cf024..d8889379c 100644 --- a/authbridge/authlib/config/config_test.go +++ b/authbridge/authlib/config/config_test.go @@ -8,7 +8,7 @@ import ( "testing" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // --- Preset Tests --- @@ -266,7 +266,7 @@ pipeline: - name: jwt-validation id: jwt-validation config: - issuer: "http://keycloak.example/realms/kagenti" + issuer: "http://keycloak.example/realms/rossoctl" bypass_paths: - /healthz - /.well-known/* @@ -293,7 +293,7 @@ pipeline: if err := json.Unmarshal(e.Config, &decoded); err != nil { t.Fatalf("config JSON parse: %v\nbytes: %s", err, e.Config) } - if decoded["issuer"] != "http://keycloak.example/realms/kagenti" { + if decoded["issuer"] != "http://keycloak.example/realms/rossoctl" { t.Errorf("issuer round-trip lost: %v", decoded["issuer"]) } paths, ok := decoded["bypass_paths"].([]any) diff --git a/authbridge/authlib/go.mod b/authbridge/authlib/go.mod index 4bc3906be..1a1a42240 100644 --- a/authbridge/authlib/go.mod +++ b/authbridge/authlib/go.mod @@ -1,4 +1,4 @@ -module github.com/kagenti/kagenti-extensions/authbridge/authlib +module github.com/rossoctl/rossocortex/authbridge/authlib go 1.26.4 @@ -7,7 +7,7 @@ require ( github.com/envoyproxy/go-control-plane/envoy v1.37.0 github.com/fsnotify/fsnotify v1.10.1 github.com/gobwas/glob v0.2.3 - github.com/kagenti/context-guru v0.0.0-20260713113308-b624f2c3d8c2 + github.com/rossoctl/context-guru v0.0.0-20260713113308-b624f2c3d8c2 github.com/lestrrat-go/jwx/v2 v2.1.7 github.com/maximhq/bifrost/core v1.7.0 github.com/open-policy-agent/opa v1.18.2 diff --git a/authbridge/authlib/go.sum b/authbridge/authlib/go.sum index bf08884d7..c34eec83c 100644 --- a/authbridge/authlib/go.sum +++ b/authbridge/authlib/go.sum @@ -124,8 +124,8 @@ github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= -github.com/kagenti/context-guru v0.0.0-20260713113308-b624f2c3d8c2 h1:nyu0kAd/+NlRM95IxEiRws2QyRtyyYRy8u8wjnwxn4o= -github.com/kagenti/context-guru v0.0.0-20260713113308-b624f2c3d8c2/go.mod h1:arqPc8H+3s+XjplrD0ytgv1Zum241jvuGu3139DX6p8= +github.com/rossoctl/context-guru v0.0.0-20260713113308-b624f2c3d8c2 h1:nyu0kAd/+NlRM95IxEiRws2QyRtyyYRy8u8wjnwxn4o= +github.com/rossoctl/context-guru v0.0.0-20260713113308-b624f2c3d8c2/go.mod h1:arqPc8H+3s+XjplrD0ytgv1Zum241jvuGu3139DX6p8= github.com/klauspost/compress v1.18.6 h1:2jupLlAwFm95+YDR+NwD2MEfFO9d4z4Prjl1XXDjuao= github.com/klauspost/compress v1.18.6/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= diff --git a/authbridge/authlib/listener/e2e/placeholder_e2e_test.go b/authbridge/authlib/listener/e2e/placeholder_e2e_test.go index 9c4e88051..77a9feca2 100644 --- a/authbridge/authlib/listener/e2e/placeholder_e2e_test.go +++ b/authbridge/authlib/listener/e2e/placeholder_e2e_test.go @@ -20,13 +20,13 @@ import ( "github.com/lestrrat-go/jwx/v2/jwk" "github.com/lestrrat-go/jwx/v2/jwt" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/listener/forwardproxy" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/listener/reverseproxy" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/placeholder" - jwtvalidation "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/jwtvalidation" - tokenexchange "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/tokenexchange" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/shared" + "github.com/rossoctl/rossocortex/authbridge/authlib/listener/forwardproxy" + "github.com/rossoctl/rossocortex/authbridge/authlib/listener/reverseproxy" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/placeholder" + jwtvalidation "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/jwtvalidation" + tokenexchange "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/tokenexchange" + "github.com/rossoctl/rossocortex/authbridge/authlib/shared" ) // startJWKS mints an RSA keypair, serves its public half as a JWKS, and diff --git a/authbridge/authlib/listener/extauthz/server.go b/authbridge/authlib/listener/extauthz/server.go index 4affc90d9..33844f203 100644 --- a/authbridge/authlib/listener/extauthz/server.go +++ b/authbridge/authlib/listener/extauthz/server.go @@ -15,8 +15,8 @@ import ( rpcstatus "google.golang.org/genproto/googleapis/rpc/status" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/auth" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/auth" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // Server implements the Envoy ext_authz Authorization gRPC service. diff --git a/authbridge/authlib/listener/extauthz/server_test.go b/authbridge/authlib/listener/extauthz/server_test.go index 1465a1fff..d09ac57e6 100644 --- a/authbridge/authlib/listener/extauthz/server_test.go +++ b/authbridge/authlib/listener/extauthz/server_test.go @@ -11,13 +11,13 @@ import ( authv3 "github.com/envoyproxy/go-control-plane/envoy/service/auth/v3" "google.golang.org/grpc/codes" - authpkg "github.com/kagenti/kagenti-extensions/authbridge/authlib/auth" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/jwtvalidation/validation" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/plugintesting" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/tokenexchange/cache" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/tokenexchange/exchange" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/routing" + authpkg "github.com/rossoctl/rossocortex/authbridge/authlib/auth" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/jwtvalidation/validation" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/plugintesting" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/tokenexchange/cache" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/tokenexchange/exchange" + "github.com/rossoctl/rossocortex/authbridge/authlib/routing" ) type mockVerifier struct { diff --git a/authbridge/authlib/listener/extproc/mcpreject_test.go b/authbridge/authlib/listener/extproc/mcpreject_test.go index 7639a0860..da2bad28b 100644 --- a/authbridge/authlib/listener/extproc/mcpreject_test.go +++ b/authbridge/authlib/listener/extproc/mcpreject_test.go @@ -8,7 +8,7 @@ import ( extprocv3 "github.com/envoyproxy/go-control-plane/envoy/service/ext_proc/v3" typev3 "github.com/envoyproxy/go-control-plane/envoy/type/v3" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // pctxWithMCP builds the minimum pctx needed to trigger the JSON-RPC diff --git a/authbridge/authlib/listener/extproc/placeholder_test.go b/authbridge/authlib/listener/extproc/placeholder_test.go index 9cde4ace6..23fe8b7e1 100644 --- a/authbridge/authlib/listener/extproc/placeholder_test.go +++ b/authbridge/authlib/listener/extproc/placeholder_test.go @@ -6,7 +6,7 @@ import ( extprocv3 "github.com/envoyproxy/go-control-plane/envoy/service/ext_proc/v3" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // mintPlugin rewrites the inbound Authorization header to a minted diff --git a/authbridge/authlib/listener/extproc/server.go b/authbridge/authlib/listener/extproc/server.go index 4cbc6d00f..3f4c9cacd 100644 --- a/authbridge/authlib/listener/extproc/server.go +++ b/authbridge/authlib/listener/extproc/server.go @@ -21,12 +21,12 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/auth" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/listener/httpx" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/listener/internal/sseframe" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/listener/skiphost" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/session" + "github.com/rossoctl/rossocortex/authbridge/authlib/auth" + "github.com/rossoctl/rossocortex/authbridge/authlib/listener/httpx" + "github.com/rossoctl/rossocortex/authbridge/authlib/listener/internal/sseframe" + "github.com/rossoctl/rossocortex/authbridge/authlib/listener/skiphost" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/session" ) const maxBodySize = 1 << 20 // 1MB — matches Envoy's default per_stream_buffer_limit_bytes diff --git a/authbridge/authlib/listener/extproc/server_test.go b/authbridge/authlib/listener/extproc/server_test.go index 61feda939..7924ec3e8 100644 --- a/authbridge/authlib/listener/extproc/server_test.go +++ b/authbridge/authlib/listener/extproc/server_test.go @@ -14,15 +14,15 @@ import ( extprocv3 "github.com/envoyproxy/go-control-plane/envoy/service/ext_proc/v3" "google.golang.org/grpc/metadata" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/auth" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/bypass" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/jwtvalidation/validation" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/plugintesting" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/tokenexchange/cache" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/tokenexchange/exchange" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/routing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/session" + "github.com/rossoctl/rossocortex/authbridge/authlib/auth" + "github.com/rossoctl/rossocortex/authbridge/authlib/bypass" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/jwtvalidation/validation" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/plugintesting" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/tokenexchange/cache" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/tokenexchange/exchange" + "github.com/rossoctl/rossocortex/authbridge/authlib/routing" + "github.com/rossoctl/rossocortex/authbridge/authlib/session" ) // mockStream implements ExternalProcessor_ProcessServer for testing. @@ -1040,13 +1040,13 @@ func TestSnapshotIdentity(t *testing.T) { name: "identity and agent both set", identity: stubIdentity{ subject: "alice", - clientID: "kagenti-ui", + clientID: "rossoctl-ui", scopes: []string{"openid", "weather-read"}, }, agent: &pipeline.AgentIdentity{WorkloadID: "spiffe://localtest.me/ns/team1/sa/weather-agent"}, want: &pipeline.EventIdentity{ Subject: "alice", - ClientID: "kagenti-ui", + ClientID: "rossoctl-ui", Scopes: []string{"openid", "weather-read"}, AgentID: "spiffe://localtest.me/ns/team1/sa/weather-agent", }, diff --git a/authbridge/authlib/listener/extproc/skiphost_test.go b/authbridge/authlib/listener/extproc/skiphost_test.go index a54399930..2e8ee7876 100644 --- a/authbridge/authlib/listener/extproc/skiphost_test.go +++ b/authbridge/authlib/listener/extproc/skiphost_test.go @@ -8,10 +8,10 @@ import ( extprocv3 "github.com/envoyproxy/go-control-plane/envoy/service/ext_proc/v3" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/listener/skiphost" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/plugintesting" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/session" + "github.com/rossoctl/rossocortex/authbridge/authlib/listener/skiphost" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/plugintesting" + "github.com/rossoctl/rossocortex/authbridge/authlib/session" ) // markerPlugin records one Invocation per OnRequest call so tests can @@ -84,7 +84,7 @@ func TestExtProc_SkipHosts_OutboundBypass(t *testing.T) { ctx: context.Background(), requests: []*extprocv3.ProcessingRequest{ outboundRequest(makeHeaders( - ":authority", "otel-collector.kagenti-system.svc.cluster.local:8335", + ":authority", "otel-collector.rossoctl-system.svc.cluster.local:8335", ":path", "/v1/traces", )), }, diff --git a/authbridge/authlib/listener/forwardproxy/mcp_sse_repro_test.go b/authbridge/authlib/listener/forwardproxy/mcp_sse_repro_test.go index 1fa1c43c9..7b66c28b4 100644 --- a/authbridge/authlib/listener/forwardproxy/mcp_sse_repro_test.go +++ b/authbridge/authlib/listener/forwardproxy/mcp_sse_repro_test.go @@ -8,10 +8,10 @@ import ( "testing" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/inferenceparser" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/mcpparser" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/session" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/inferenceparser" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/mcpparser" + "github.com/rossoctl/rossocortex/authbridge/authlib/session" ) // TestForwardProxy_MCP_SSEResponse_RecordsObserve reproduces the live diff --git a/authbridge/authlib/listener/forwardproxy/mcp_sse_stream_test.go b/authbridge/authlib/listener/forwardproxy/mcp_sse_stream_test.go index a68da382f..3587f0047 100644 --- a/authbridge/authlib/listener/forwardproxy/mcp_sse_stream_test.go +++ b/authbridge/authlib/listener/forwardproxy/mcp_sse_stream_test.go @@ -14,8 +14,8 @@ import ( "testing" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/session" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/session" ) // TestForwardProxy_SSE_StreamsWithoutResponder is the regression test for diff --git a/authbridge/authlib/listener/forwardproxy/server.go b/authbridge/authlib/listener/forwardproxy/server.go index 8d2a6472a..ab54ab8f6 100644 --- a/authbridge/authlib/listener/forwardproxy/server.go +++ b/authbridge/authlib/listener/forwardproxy/server.go @@ -19,15 +19,15 @@ import ( "sync" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/auth" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/listener/httpx" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/listener/internal/sseframe" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/listener/skiphost" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/session" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/spiffe" - authtls "github.com/kagenti/kagenti-extensions/authbridge/authlib/tls" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/tlsbridge" + "github.com/rossoctl/rossocortex/authbridge/authlib/auth" + "github.com/rossoctl/rossocortex/authbridge/authlib/listener/httpx" + "github.com/rossoctl/rossocortex/authbridge/authlib/listener/internal/sseframe" + "github.com/rossoctl/rossocortex/authbridge/authlib/listener/skiphost" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/session" + "github.com/rossoctl/rossocortex/authbridge/authlib/spiffe" + authtls "github.com/rossoctl/rossocortex/authbridge/authlib/tls" + "github.com/rossoctl/rossocortex/authbridge/authlib/tlsbridge" ) const maxBodySize = 1 << 20 // 1MB — matches Envoy's default per_stream_buffer_limit_bytes diff --git a/authbridge/authlib/listener/forwardproxy/server_test.go b/authbridge/authlib/listener/forwardproxy/server_test.go index bd06b718e..565afe93e 100644 --- a/authbridge/authlib/listener/forwardproxy/server_test.go +++ b/authbridge/authlib/listener/forwardproxy/server_test.go @@ -13,14 +13,14 @@ import ( "testing" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/auth" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/jwtvalidation/validation" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/plugintesting" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/tokenexchange/cache" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/tokenexchange/exchange" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/routing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/session" + "github.com/rossoctl/rossocortex/authbridge/authlib/auth" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/jwtvalidation/validation" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/plugintesting" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/tokenexchange/cache" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/tokenexchange/exchange" + "github.com/rossoctl/rossocortex/authbridge/authlib/routing" + "github.com/rossoctl/rossocortex/authbridge/authlib/session" ) type mockVerifier struct { diff --git a/authbridge/authlib/listener/forwardproxy/session_pin_test.go b/authbridge/authlib/listener/forwardproxy/session_pin_test.go index b7d903fc7..d9dc6ab2f 100644 --- a/authbridge/authlib/listener/forwardproxy/session_pin_test.go +++ b/authbridge/authlib/listener/forwardproxy/session_pin_test.go @@ -4,8 +4,8 @@ import ( "testing" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/session" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/session" ) // TestRecordOutboundResponse_PinsRequestSession is the regression guard for diff --git a/authbridge/authlib/listener/forwardproxy/skiphost_test.go b/authbridge/authlib/listener/forwardproxy/skiphost_test.go index b110ee6ee..9bd13ef44 100644 --- a/authbridge/authlib/listener/forwardproxy/skiphost_test.go +++ b/authbridge/authlib/listener/forwardproxy/skiphost_test.go @@ -12,10 +12,10 @@ import ( "testing" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/listener/skiphost" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/plugintesting" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/session" + "github.com/rossoctl/rossocortex/authbridge/authlib/listener/skiphost" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/plugintesting" + "github.com/rossoctl/rossocortex/authbridge/authlib/session" ) // markerPlugin records one Invocation per OnRequest call. Tests use it to diff --git a/authbridge/authlib/listener/forwardproxy/streaming_test.go b/authbridge/authlib/listener/forwardproxy/streaming_test.go index 88c5ea9c6..1c7388589 100644 --- a/authbridge/authlib/listener/forwardproxy/streaming_test.go +++ b/authbridge/authlib/listener/forwardproxy/streaming_test.go @@ -13,7 +13,7 @@ import ( "testing" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // streamingProbe is a minimal Plugin + StreamingResponder used to diff --git a/authbridge/authlib/listener/forwardproxy/tlsbridge_integration_test.go b/authbridge/authlib/listener/forwardproxy/tlsbridge_integration_test.go index 1e3b494b2..7c5670f66 100644 --- a/authbridge/authlib/listener/forwardproxy/tlsbridge_integration_test.go +++ b/authbridge/authlib/listener/forwardproxy/tlsbridge_integration_test.go @@ -15,9 +15,9 @@ import ( "testing" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/plugintesting" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/tlsbridge" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/plugintesting" + "github.com/rossoctl/rossocortex/authbridge/authlib/tlsbridge" ) // bridgeProbePlugin records the decrypted request method/path/headers it sees. diff --git a/authbridge/authlib/listener/forwardproxy/transparent.go b/authbridge/authlib/listener/forwardproxy/transparent.go index aa0892820..2883fc210 100644 --- a/authbridge/authlib/listener/forwardproxy/transparent.go +++ b/authbridge/authlib/listener/forwardproxy/transparent.go @@ -8,9 +8,9 @@ import ( "net/http" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/session" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/tlsbridge" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/session" + "github.com/rossoctl/rossocortex/authbridge/authlib/tlsbridge" ) // HandleTransparentConn processes one outbound connection captured by an diff --git a/authbridge/authlib/listener/forwardproxy/transparent_test.go b/authbridge/authlib/listener/forwardproxy/transparent_test.go index d8da40fed..2d203eaae 100644 --- a/authbridge/authlib/listener/forwardproxy/transparent_test.go +++ b/authbridge/authlib/listener/forwardproxy/transparent_test.go @@ -6,9 +6,9 @@ import ( "testing" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/plugintesting" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/session" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/plugintesting" + "github.com/rossoctl/rossocortex/authbridge/authlib/session" ) // TestRecordTunnelOpened_SetsTunnelMarker locks the explicit producer marker: diff --git a/authbridge/authlib/listener/httpx/render.go b/authbridge/authlib/listener/httpx/render.go index 414f673b5..940c1261e 100644 --- a/authbridge/authlib/listener/httpx/render.go +++ b/authbridge/authlib/listener/httpx/render.go @@ -7,7 +7,7 @@ import ( "encoding/json" "net/http" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // WriteRejection renders a pipeline.Reject Action onto an HTTP diff --git a/authbridge/authlib/listener/httpx/render_test.go b/authbridge/authlib/listener/httpx/render_test.go index 93d3f8d29..db80e600d 100644 --- a/authbridge/authlib/listener/httpx/render_test.go +++ b/authbridge/authlib/listener/httpx/render_test.go @@ -6,7 +6,7 @@ import ( "net/http/httptest" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // mcpAction matches what mcp-parser populates plus what ibac (or any diff --git a/authbridge/authlib/listener/internal/tlssniff/listener_test.go b/authbridge/authlib/listener/internal/tlssniff/listener_test.go index 1eb4de343..73d137040 100644 --- a/authbridge/authlib/listener/internal/tlssniff/listener_test.go +++ b/authbridge/authlib/listener/internal/tlssniff/listener_test.go @@ -16,7 +16,7 @@ import ( "testing" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/listener/internal/tlssniff" + "github.com/rossoctl/rossocortex/authbridge/authlib/listener/internal/tlssniff" ) // TestPermissive_ServesTLS confirms that a TLS handshake byte (0x16) diff --git a/authbridge/authlib/listener/reverseproxy/finisher_test.go b/authbridge/authlib/listener/reverseproxy/finisher_test.go index aa86fbf89..7a78d4781 100644 --- a/authbridge/authlib/listener/reverseproxy/finisher_test.go +++ b/authbridge/authlib/listener/reverseproxy/finisher_test.go @@ -8,8 +8,8 @@ import ( "testing" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/plugintesting" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/plugintesting" ) // waitSeen polls b until it's true, up to ~1s. OnFinish runs in the diff --git a/authbridge/authlib/listener/reverseproxy/placeholder_test.go b/authbridge/authlib/listener/reverseproxy/placeholder_test.go index 0ca6ec0c2..b3323ff45 100644 --- a/authbridge/authlib/listener/reverseproxy/placeholder_test.go +++ b/authbridge/authlib/listener/reverseproxy/placeholder_test.go @@ -6,7 +6,7 @@ import ( "net/http/httptest" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // rewritePlugin sets a new Authorization on the inbound context, simulating diff --git a/authbridge/authlib/listener/reverseproxy/recording_test.go b/authbridge/authlib/listener/reverseproxy/recording_test.go index 0feac2401..c31cbea3f 100644 --- a/authbridge/authlib/listener/reverseproxy/recording_test.go +++ b/authbridge/authlib/listener/reverseproxy/recording_test.go @@ -7,8 +7,8 @@ import ( "testing" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/session" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/session" ) // allowOnlyPlugin records an ALLOW invocation but never sets diff --git a/authbridge/authlib/listener/reverseproxy/server.go b/authbridge/authlib/listener/reverseproxy/server.go index 8a5eba5b6..57889699d 100644 --- a/authbridge/authlib/listener/reverseproxy/server.go +++ b/authbridge/authlib/listener/reverseproxy/server.go @@ -17,13 +17,13 @@ import ( "strings" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/listener/httpx" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/listener/internal/sseframe" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/listener/internal/tlssniff" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/session" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/spiffe" - authtls "github.com/kagenti/kagenti-extensions/authbridge/authlib/tls" + "github.com/rossoctl/rossocortex/authbridge/authlib/listener/httpx" + "github.com/rossoctl/rossocortex/authbridge/authlib/listener/internal/sseframe" + "github.com/rossoctl/rossocortex/authbridge/authlib/listener/internal/tlssniff" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/session" + "github.com/rossoctl/rossocortex/authbridge/authlib/spiffe" + authtls "github.com/rossoctl/rossocortex/authbridge/authlib/tls" ) const maxBodySize = 1 << 20 // 1MB — matches Envoy's default per_stream_buffer_limit_bytes diff --git a/authbridge/authlib/listener/reverseproxy/server_test.go b/authbridge/authlib/listener/reverseproxy/server_test.go index 3ff2d6daa..6da6b4b43 100644 --- a/authbridge/authlib/listener/reverseproxy/server_test.go +++ b/authbridge/authlib/listener/reverseproxy/server_test.go @@ -10,12 +10,12 @@ import ( "testing" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/auth" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/bypass" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/jwtvalidation/validation" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/plugintesting" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/session" + "github.com/rossoctl/rossocortex/authbridge/authlib/auth" + "github.com/rossoctl/rossocortex/authbridge/authlib/bypass" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/jwtvalidation/validation" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/plugintesting" + "github.com/rossoctl/rossocortex/authbridge/authlib/session" ) type mockVerifier struct { diff --git a/authbridge/authlib/listener/reverseproxy/streaming_test.go b/authbridge/authlib/listener/reverseproxy/streaming_test.go index 25fa7d305..f8e045e65 100644 --- a/authbridge/authlib/listener/reverseproxy/streaming_test.go +++ b/authbridge/authlib/listener/reverseproxy/streaming_test.go @@ -13,7 +13,7 @@ import ( "testing" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // streamingProbe is a Plugin + StreamingResponder for asserting on diff --git a/authbridge/authlib/listener/skiphost/skiphost.go b/authbridge/authlib/listener/skiphost/skiphost.go index 49d463b1b..a1d604964 100644 --- a/authbridge/authlib/listener/skiphost/skiphost.go +++ b/authbridge/authlib/listener/skiphost/skiphost.go @@ -93,7 +93,7 @@ func New(patterns []string) (*Matcher, error) { // Match reports whether host matches any configured pattern. Strips // the port (everything from the first colon) before comparing so -// operators can write "otel-collector.kagenti-system.svc.cluster.local" +// operators can write "otel-collector.rossoctl-system.svc.cluster.local" // without worrying which port the upstream listens on. Returns false // for the nil Matcher and for the empty host. // diff --git a/authbridge/authlib/listener/skiphost/skiphost_test.go b/authbridge/authlib/listener/skiphost/skiphost_test.go index 1948a0af0..29efe1307 100644 --- a/authbridge/authlib/listener/skiphost/skiphost_test.go +++ b/authbridge/authlib/listener/skiphost/skiphost_test.go @@ -85,8 +85,8 @@ func TestNew_AcceptsLeadingStar(t *testing.T) { } func TestMatch_StripsPort(t *testing.T) { - m, _ := New([]string{"otel-collector.kagenti-system.svc.cluster.local"}) - if !m.Match("otel-collector.kagenti-system.svc.cluster.local:8335") { + m, _ := New([]string{"otel-collector.rossoctl-system.svc.cluster.local"}) + if !m.Match("otel-collector.rossoctl-system.svc.cluster.local:8335") { t.Error("port-stripping failed: pattern without :port should match host with :port") } } @@ -100,7 +100,7 @@ func TestMatch_GlobSingleLabel(t *testing.T) { }{ {"otel-collector", true}, {"otel-collector-v2", true}, - {"otel-collector.kagenti-system.svc.cluster.local", false}, // separator stops at . + {"otel-collector.rossoctl-system.svc.cluster.local", false}, // separator stops at . {"foo-otel-collector", false}, } for _, tc := range cases { @@ -112,11 +112,11 @@ func TestMatch_GlobSingleLabel(t *testing.T) { func TestMatch_GlobLeadingWildcard(t *testing.T) { // `*.svc.cluster.local` → single-label prefix on a fixed suffix. - m, _ := New([]string{"*.kagenti-system.svc.cluster.local"}) - if !m.Match("otel-collector.kagenti-system.svc.cluster.local") { + m, _ := New([]string{"*.rossoctl-system.svc.cluster.local"}) + if !m.Match("otel-collector.rossoctl-system.svc.cluster.local") { t.Error("leading-* should match a single-label prefix on the FQDN") } - if m.Match("a.b.kagenti-system.svc.cluster.local") { + if m.Match("a.b.rossoctl-system.svc.cluster.local") { t.Error("leading-* must NOT match a two-label prefix (separator semantics)") } } diff --git a/authbridge/authlib/listener/transparentproxy/origdst_linux.go b/authbridge/authlib/listener/transparentproxy/origdst_linux.go index 2ea3cf55b..c89123aa1 100644 --- a/authbridge/authlib/listener/transparentproxy/origdst_linux.go +++ b/authbridge/authlib/listener/transparentproxy/origdst_linux.go @@ -50,7 +50,7 @@ func getOrigDst(fd uintptr) (string, error) { var buf [unix.SizeofSockaddrInet6]byte size := uint32(len(buf)) - // IPv4 (SOL_IP) first — the common case in kagenti clusters. + // IPv4 (SOL_IP) first — the common case in rossoctl clusters. if errno := getsockopt(fd, unix.SOL_IP, soOriginalDst, &buf[0], &size); errno == 0 { return parseSockaddr(buf[:size]) } diff --git a/authbridge/authlib/llmclient/README.md b/authbridge/authlib/llmclient/README.md index a651751bc..31b6808f7 100644 --- a/authbridge/authlib/llmclient/README.md +++ b/authbridge/authlib/llmclient/README.md @@ -7,7 +7,7 @@ The package exists so plugin authors don't rewrite ~150 LOC of HTTP plumbing, JS ## Quick start ```go -import "github.com/kagenti/kagenti-extensions/authbridge/authlib/llmclient" +import "github.com/rossoctl/rossocortex/authbridge/authlib/llmclient" c := llmclient.New(llmclient.Options{ Endpoint: "http://host.docker.internal:11434", diff --git a/authbridge/authlib/llmclient/client_test.go b/authbridge/authlib/llmclient/client_test.go index 22f0f7006..7cc8018fb 100644 --- a/authbridge/authlib/llmclient/client_test.go +++ b/authbridge/authlib/llmclient/client_test.go @@ -11,7 +11,7 @@ import ( "testing" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/llmclient" + "github.com/rossoctl/rossocortex/authbridge/authlib/llmclient" ) // Smallest possible response shape — the server always returns diff --git a/authbridge/authlib/observe/statserver.go b/authbridge/authlib/observe/statserver.go index b19edac4e..c4c7b5219 100644 --- a/authbridge/authlib/observe/statserver.go +++ b/authbridge/authlib/observe/statserver.go @@ -8,9 +8,9 @@ import ( "net/http" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/auth" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/config" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/redact" + "github.com/rossoctl/rossocortex/authbridge/authlib/auth" + "github.com/rossoctl/rossocortex/authbridge/authlib/config" + "github.com/rossoctl/rossocortex/authbridge/authlib/redact" ) type StatServer struct { @@ -69,8 +69,8 @@ func NewStatServer(addr string, configProvider ConfigProvider, statsProvider Sta diff --git a/authbridge/authlib/observe/statserver_test.go b/authbridge/authlib/observe/statserver_test.go index 22b9c8ada..d346128e3 100644 --- a/authbridge/authlib/observe/statserver_test.go +++ b/authbridge/authlib/observe/statserver_test.go @@ -8,8 +8,8 @@ import ( "strings" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/auth" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/config" + "github.com/rossoctl/rossocortex/authbridge/authlib/auth" + "github.com/rossoctl/rossocortex/authbridge/authlib/config" ) func newTestConfig() *config.Config { diff --git a/authbridge/authlib/pipeline/action_test.go b/authbridge/authlib/pipeline/action_test.go index 7dd79bdcf..62ac991d0 100644 --- a/authbridge/authlib/pipeline/action_test.go +++ b/authbridge/authlib/pipeline/action_test.go @@ -35,7 +35,7 @@ func TestViolation_Render_DefaultBody(t *testing.T) { Code: "auth.missing-token", Reason: "Bearer required", Description: "No Authorization header present", - Details: map[string]any{"realm": "kagenti"}, + Details: map[string]any{"realm": "rossoctl"}, PluginName: "jwt-validation", } status, headers, body := v.Render() @@ -67,7 +67,7 @@ func TestViolation_Render_DefaultBody(t *testing.T) { if !ok { t.Fatalf("details not a map: %v", got["details"]) } - if details["realm"] != "kagenti" { + if details["realm"] != "rossoctl" { t.Errorf("details.realm = %v", details["realm"]) } } @@ -113,14 +113,14 @@ func TestViolation_Render_PreservesAndClonesHeaders(t *testing.T) { // Use http.Header.Set so the key is canonicalized by the stdlib — this // mirrors what a real plugin would do via the Challenge() helper. origHeaders := http.Header{} - origHeaders.Set("WWW-Authenticate", `Bearer realm="kagenti"`) + origHeaders.Set("WWW-Authenticate", `Bearer realm="rossoctl"`) v := &Violation{ Code: "auth.missing-token", Reason: "bearer required", Headers: origHeaders, } _, h, _ := v.Render() - if got := h.Get("WWW-Authenticate"); got != `Bearer realm="kagenti"` { + if got := h.Get("WWW-Authenticate"); got != `Bearer realm="rossoctl"` { t.Errorf("WWW-Authenticate = %q", got) } if h.Get("Content-Type") == "" { @@ -194,12 +194,12 @@ func TestDenyWithDetails(t *testing.T) { } func TestChallenge(t *testing.T) { - a := Challenge("kagenti", "Authorization required") + a := Challenge("rossoctl", "Authorization required") status, h, _ := a.Violation.Render() if status != 401 { t.Errorf("status = %d", status) } - if got := h.Get("WWW-Authenticate"); got != `Bearer realm="kagenti"` { + if got := h.Get("WWW-Authenticate"); got != `Bearer realm="rossoctl"` { t.Errorf("WWW-Authenticate = %q", got) } } diff --git a/authbridge/authlib/pipeline/content.go b/authbridge/authlib/pipeline/content.go index 7e8b8165f..d99aff805 100644 --- a/authbridge/authlib/pipeline/content.go +++ b/authbridge/authlib/pipeline/content.go @@ -5,7 +5,7 @@ import ( "fmt" "log/slog" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/contracts" + "github.com/rossoctl/rossocortex/authbridge/authlib/contracts" ) // This file wires the named protocol extensions (A2AExtension, diff --git a/authbridge/authlib/pipeline/content_test.go b/authbridge/authlib/pipeline/content_test.go index 3d0f19d28..463a83143 100644 --- a/authbridge/authlib/pipeline/content_test.go +++ b/authbridge/authlib/pipeline/content_test.go @@ -5,7 +5,7 @@ import ( "sort" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/contracts" + "github.com/rossoctl/rossocortex/authbridge/authlib/contracts" ) func TestA2AExtension_Fragments(t *testing.T) { diff --git a/authbridge/authlib/pipeline/context.go b/authbridge/authlib/pipeline/context.go index e1e801a9c..1076eb252 100644 --- a/authbridge/authlib/pipeline/context.go +++ b/authbridge/authlib/pipeline/context.go @@ -10,7 +10,7 @@ import ( "net/http" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/contracts" + "github.com/rossoctl/rossocortex/authbridge/authlib/contracts" ) // Identity carries the subject identity established by whichever auth diff --git a/authbridge/authlib/pipeline/schema.go b/authbridge/authlib/pipeline/schema.go index b00218970..3258d82d3 100644 --- a/authbridge/authlib/pipeline/schema.go +++ b/authbridge/authlib/pipeline/schema.go @@ -19,7 +19,7 @@ // metadata" — the field appears in the schema but with empty fields. // // This package owns the shape; presentation (template YAML, hover -// formatting, JSON Schema) lives in the consumer (abctl, kagenti UI, +// formatting, JSON Schema) lives in the consumer (abctl, rossoctl UI, // future generators). package pipeline @@ -31,7 +31,7 @@ import ( // SchemaProvider is implemented by plugins whose config field // metadata should appear in the catalog and downstream tooling -// (abctl edit templates, future kagenti-UI forms, JSON Schema +// (abctl edit templates, future rossoctl-UI forms, JSON Schema // generators). Plugins without configs (a2a-parser, // inference-parser today) can omit this interface. // diff --git a/authbridge/authlib/pipeline/session_test.go b/authbridge/authlib/pipeline/session_test.go index 467676321..932ca3fb2 100644 --- a/authbridge/authlib/pipeline/session_test.go +++ b/authbridge/authlib/pipeline/session_test.go @@ -154,7 +154,7 @@ func TestSessionEvent_Invocations_JSONRoundTrip(t *testing.T) { Action: ActionDeny, Reason: "jwt_failed", Details: map[string]string{ - "expected_issuer": "http://keycloak.localtest.me:8080/realms/kagenti", + "expected_issuer": "http://keycloak.localtest.me:8080/realms/rossoctl", "expected_audience": "spiffe://localtest.me/ns/team1/sa/weather-tool", }, }}, diff --git a/authbridge/authlib/pipeline/sharedstore_test.go b/authbridge/authlib/pipeline/sharedstore_test.go index 839eaf9db..06e0b5be4 100644 --- a/authbridge/authlib/pipeline/sharedstore_test.go +++ b/authbridge/authlib/pipeline/sharedstore_test.go @@ -3,8 +3,8 @@ package pipeline_test import ( "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/shared" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/shared" ) // shared.Store must satisfy pipeline.SharedStore so listeners can inject it. diff --git a/authbridge/authlib/pipeline/snapshot_test.go b/authbridge/authlib/pipeline/snapshot_test.go index 8c870a124..60dae7145 100644 --- a/authbridge/authlib/pipeline/snapshot_test.go +++ b/authbridge/authlib/pipeline/snapshot_test.go @@ -113,7 +113,7 @@ func TestSnapshotIdentity_FromIdentity(t *testing.T) { pctx := &Context{ Identity: stubIdentity{ subject: "alice", - clientID: "kagenti-ui", + clientID: "rossoctl-ui", scopes: []string{"openid", "agent-aud"}, }, } @@ -121,8 +121,8 @@ func TestSnapshotIdentity_FromIdentity(t *testing.T) { if got == nil { t.Fatal("SnapshotIdentity returned nil despite populated Identity") } - if got.Subject != "alice" || got.ClientID != "kagenti-ui" { - t.Errorf("Subject/ClientID = %q/%q, want alice/kagenti-ui", got.Subject, got.ClientID) + if got.Subject != "alice" || got.ClientID != "rossoctl-ui" { + t.Errorf("Subject/ClientID = %q/%q, want alice/rossoctl-ui", got.Subject, got.ClientID) } if len(got.Scopes) != 2 || got.Scopes[0] != "openid" { t.Errorf("Scopes = %v, want [openid agent-aud]", got.Scopes) diff --git a/authbridge/authlib/plugins/a2aparser/plugin.go b/authbridge/authlib/plugins/a2aparser/plugin.go index 7319b14ce..12b4887c7 100644 --- a/authbridge/authlib/plugins/a2aparser/plugin.go +++ b/authbridge/authlib/plugins/a2aparser/plugin.go @@ -6,9 +6,9 @@ import ( "encoding/json" "log/slog" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/internal/parsercommon" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/internal/parsercommon" ) // A2AParser parses A2A JSON-RPC 2.0 request bodies and populates @@ -57,7 +57,7 @@ func (p *A2AParser) OnRequest(_ context.Context, pctx *pipeline.Context) pipelin // Extract message fields generically — any method with params.message // gets full extraction (forward-compatible with future A2A methods). // A2A spec uses "contextId" (current) or "sessionId" (older drafts). - // Some A2A clients (notably the Python SDK used by the kagenti backend) + // Some A2A clients (notably the Python SDK used by the rossoctl backend) // place contextId INSIDE params.message rather than at the top-level // params, so fall through to params.message.contextId when neither // top-level slot is set. Without this fallback every inbound turn of diff --git a/authbridge/authlib/plugins/a2aparser/plugin_test.go b/authbridge/authlib/plugins/a2aparser/plugin_test.go index 4abf0a6ff..2e485a1ab 100644 --- a/authbridge/authlib/plugins/a2aparser/plugin_test.go +++ b/authbridge/authlib/plugins/a2aparser/plugin_test.go @@ -4,7 +4,7 @@ import ( "context" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) func TestA2AParser_Capabilities(t *testing.T) { @@ -85,7 +85,7 @@ func TestA2AParser_MessageStream(t *testing.T) { } } -// The A2A Python SDK (and the kagenti backend that wraps it) places contextId +// The A2A Python SDK (and the rossoctl backend that wraps it) places contextId // inside params.message on established-conversation turns — not at the // top-level params that the earlier extraction path looked at. Without this // fallback, the listener's request-phase session lookup sees an empty diff --git a/authbridge/authlib/plugins/a2aparser/streaming_test.go b/authbridge/authlib/plugins/a2aparser/streaming_test.go index b32f93938..e751014bc 100644 --- a/authbridge/authlib/plugins/a2aparser/streaming_test.go +++ b/authbridge/authlib/plugins/a2aparser/streaming_test.go @@ -4,7 +4,7 @@ import ( "context" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) func TestA2AParser_OnResponseFrame_FoldsArtifactAndFinalStatus(t *testing.T) { diff --git a/authbridge/authlib/plugins/contextguru/build_test.go b/authbridge/authlib/plugins/contextguru/build_test.go index 68ec55595..a778ed14f 100644 --- a/authbridge/authlib/plugins/contextguru/build_test.go +++ b/authbridge/authlib/plugins/contextguru/build_test.go @@ -4,11 +4,11 @@ import ( "encoding/json" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/config" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins" + "github.com/rossoctl/rossocortex/authbridge/authlib/config" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins" // Register inference-parser so context-guru's RequiresAny is satisfiable. - _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/inferenceparser" + _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/inferenceparser" ) // TestBuild_InChainAfterInferenceParser confirms the plugin assembles on the diff --git a/authbridge/authlib/plugins/contextguru/plugin.go b/authbridge/authlib/plugins/contextguru/plugin.go index c719c26f8..d81a8eed4 100644 --- a/authbridge/authlib/plugins/contextguru/plugin.go +++ b/authbridge/authlib/plugins/contextguru/plugin.go @@ -1,6 +1,6 @@ // Package contextguru is an outbound AuthBridge plugin that compacts an agent's // LLM request context before it is forwarded upstream, using the embedded -// github.com/kagenti/context-guru engine. It runs in the pre-LLM hook +// github.com/rossoctl/context-guru engine. It runs in the pre-LLM hook // (OnRequest): it hands the outbound request body to apply.BodyWithModel, and if // the engine rewrote it (dropped/reduced tool outputs, injected cache_control, // etc.) it replaces the body via pctx.SetBody. OnResponse is a pass-through in @@ -26,16 +26,16 @@ import ( "strings" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/llmclient" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins" + "github.com/rossoctl/rossocortex/authbridge/authlib/llmclient" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins" - "github.com/kagenti/context-guru/apply" - cgcomponents "github.com/kagenti/context-guru/components" - _ "github.com/kagenti/context-guru/components/offload" // register offload components - _ "github.com/kagenti/context-guru/components/reformat" // register reformat components - cgconfig "github.com/kagenti/context-guru/config" - cgstore "github.com/kagenti/context-guru/store" + "github.com/rossoctl/context-guru/apply" + cgcomponents "github.com/rossoctl/context-guru/components" + _ "github.com/rossoctl/context-guru/components/offload" // register offload components + _ "github.com/rossoctl/context-guru/components/reformat" // register reformat components + cgconfig "github.com/rossoctl/context-guru/config" + cgstore "github.com/rossoctl/context-guru/store" bschemas "github.com/maximhq/bifrost/core/schemas" ) diff --git a/authbridge/authlib/plugins/contextguru/plugin_test.go b/authbridge/authlib/plugins/contextguru/plugin_test.go index a0875e9c3..a3d5c09fd 100644 --- a/authbridge/authlib/plugins/contextguru/plugin_test.go +++ b/authbridge/authlib/plugins/contextguru/plugin_test.go @@ -7,7 +7,7 @@ import ( "strings" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" bschemas "github.com/maximhq/bifrost/core/schemas" ) diff --git a/authbridge/authlib/plugins/cpex/README.md b/authbridge/authlib/plugins/cpex/README.md index 4a28934ab..26a6c262d 100644 --- a/authbridge/authlib/plugins/cpex/README.md +++ b/authbridge/authlib/plugins/cpex/README.md @@ -29,7 +29,7 @@ That orchestration allows you to see the full scope of your authorization flow ( ## How it works -AuthBridge parses traffic into a typed pipeline context ([inspired by CPEX's specification](https://github.com/kagenti/kagenti-extensions/commit/4c53164d02809ddb19f3b79b3abf9c288a8bc4fb)). +AuthBridge parses traffic into a typed pipeline context ([inspired by CPEX's specification](https://github.com/rossoctl/rossocortex/commit/4c53164d02809ddb19f3b79b3abf9c288a8bc4fb)). The cpex plugin projects that context into CMF (a normalized, typed policy context), invokes the CPEX hooks the operator configured, applies any modifications CPEX returns (redacted bodies, mutated headers, session labels), and maps the CPEX outcome diff --git a/authbridge/authlib/plugins/cpex/cmf_a2a.go b/authbridge/authlib/plugins/cpex/cmf_a2a.go index e6bb3ac27..47a08a8d8 100644 --- a/authbridge/authlib/plugins/cpex/cmf_a2a.go +++ b/authbridge/authlib/plugins/cpex/cmf_a2a.go @@ -4,7 +4,7 @@ import ( "encoding/json" "fmt" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // A2A (JSON-RPC) body write-back. Like the inference re-serializers, the diff --git a/authbridge/authlib/plugins/cpex/cmf_a2a_test.go b/authbridge/authlib/plugins/cpex/cmf_a2a_test.go index 0ec5e60c2..b2bd1e046 100644 --- a/authbridge/authlib/plugins/cpex/cmf_a2a_test.go +++ b/authbridge/authlib/plugins/cpex/cmf_a2a_test.go @@ -4,7 +4,7 @@ import ( "encoding/json" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // --- a2aToCMFParts (request) --- diff --git a/authbridge/authlib/plugins/cpex/cmf_body.go b/authbridge/authlib/plugins/cpex/cmf_body.go index 67f731a26..64306c208 100644 --- a/authbridge/authlib/plugins/cpex/cmf_body.go +++ b/authbridge/authlib/plugins/cpex/cmf_body.go @@ -8,7 +8,7 @@ import ( "strconv" "strings" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // isStreamingResponseGap reports whether a response-phase invocation has a diff --git a/authbridge/authlib/plugins/cpex/cmf_body_test.go b/authbridge/authlib/plugins/cpex/cmf_body_test.go index 111e4f2b7..32c439cc1 100644 --- a/authbridge/authlib/plugins/cpex/cmf_body_test.go +++ b/authbridge/authlib/plugins/cpex/cmf_body_test.go @@ -6,7 +6,7 @@ import ( "strings" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // --- applyMCPRequestBodyMod --- diff --git a/authbridge/authlib/plugins/cpex/cmf_inference.go b/authbridge/authlib/plugins/cpex/cmf_inference.go index f06c46af8..8f93a356b 100644 --- a/authbridge/authlib/plugins/cpex/cmf_inference.go +++ b/authbridge/authlib/plugins/cpex/cmf_inference.go @@ -4,7 +4,7 @@ import ( "encoding/json" "fmt" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // Inference (OpenAI chat/completions) body write-back. The cgo adapter diff --git a/authbridge/authlib/plugins/cpex/cmf_inference_test.go b/authbridge/authlib/plugins/cpex/cmf_inference_test.go index 7e48cd822..9565d4e12 100644 --- a/authbridge/authlib/plugins/cpex/cmf_inference_test.go +++ b/authbridge/authlib/plugins/cpex/cmf_inference_test.go @@ -5,7 +5,7 @@ import ( "reflect" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // --- inferenceToCMFParts (request) --- diff --git a/authbridge/authlib/plugins/cpex/config.go b/authbridge/authlib/plugins/cpex/config.go index 02efe2e25..b1a55da1d 100644 --- a/authbridge/authlib/plugins/cpex/config.go +++ b/authbridge/authlib/plugins/cpex/config.go @@ -17,7 +17,7 @@ import ( // `global:` / `plugin_settings:` YAML that CPEX itself parses) is // supplied either inline via `config` or by path via `config_file`. // Operators read CPEX docs verbatim and the YAML format is what they -// would write for CPEX directly — no kagenti-side re-shaping. +// would write for CPEX directly — no rossoctl-side re-shaping. // // A cpex plugin with no `hooks`, no `config`, and no `config_file` is // installed but inert — Configure succeeds; OnRequest/OnResponse @@ -75,7 +75,7 @@ type cpexConfig struct { // BypassPaths is a list of URL path glob patterns (path.Match // syntax) whose requests skip CPEX entirely. Defaults to liveness/ // readiness probes + .well-known discovery; operators add their - // own. Uses kagenti's shared bypass package so semantics match + // own. Uses rossoctl's shared bypass package so semantics match // jwt-validation, ibac, etc. BypassPaths []string `json:"bypass_paths" description:"URL path globs whose requests skip CPEX. Defaults to /healthz, /readyz, /livez, /.well-known/*."` } diff --git a/authbridge/authlib/plugins/cpex/manager.go b/authbridge/authlib/plugins/cpex/manager.go index 46d7c3108..4371f9806 100644 --- a/authbridge/authlib/plugins/cpex/manager.go +++ b/authbridge/authlib/plugins/cpex/manager.go @@ -3,7 +3,7 @@ package cpex import ( "context" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // Manager is the surface plugin.go uses to talk to CPEX. It is a diff --git a/authbridge/authlib/plugins/cpex/manager_cpex.go b/authbridge/authlib/plugins/cpex/manager_cpex.go index 89bfc8788..28b6c3524 100644 --- a/authbridge/authlib/plugins/cpex/manager_cpex.go +++ b/authbridge/authlib/plugins/cpex/manager_cpex.go @@ -11,8 +11,8 @@ import ( "time" rcpex "github.com/contextforge-org/cpex/go/cpex" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/contracts" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/contracts" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // cpexManager is the CPEX-backed Manager implementation. Wraps diff --git a/authbridge/authlib/plugins/cpex/manager_test.go b/authbridge/authlib/plugins/cpex/manager_test.go index df5d7b891..37a89e0bf 100644 --- a/authbridge/authlib/plugins/cpex/manager_test.go +++ b/authbridge/authlib/plugins/cpex/manager_test.go @@ -4,7 +4,7 @@ import ( "context" "sync" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // FakeManager is a programmable Manager for unit tests. Set Hooks, diff --git a/authbridge/authlib/plugins/cpex/plugin.go b/authbridge/authlib/plugins/cpex/plugin.go index fc62d96e0..295ae8d4c 100644 --- a/authbridge/authlib/plugins/cpex/plugin.go +++ b/authbridge/authlib/plugins/cpex/plugin.go @@ -57,9 +57,9 @@ import ( "strings" "sync/atomic" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/bypass" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins" + "github.com/rossoctl/rossocortex/authbridge/authlib/bypass" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins" ) // CPEX is the AuthBridge plugin chassis around a CPEX PluginManager. diff --git a/authbridge/authlib/plugins/cpex/plugin_test.go b/authbridge/authlib/plugins/cpex/plugin_test.go index 767ba796e..edbbc05ae 100644 --- a/authbridge/authlib/plugins/cpex/plugin_test.go +++ b/authbridge/authlib/plugins/cpex/plugin_test.go @@ -9,7 +9,7 @@ import ( "strings" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // Canonical test-config strings. Most dispatch tests want a single diff --git a/authbridge/authlib/plugins/ibac/judge.go b/authbridge/authlib/plugins/ibac/judge.go index a61f2b6b6..583492f69 100644 --- a/authbridge/authlib/plugins/ibac/judge.go +++ b/authbridge/authlib/plugins/ibac/judge.go @@ -7,7 +7,7 @@ import ( "strings" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/llmclient" + "github.com/rossoctl/rossocortex/authbridge/authlib/llmclient" ) // Judge evaluates whether a proposed agent action aligns with a recorded diff --git a/authbridge/authlib/plugins/ibac/judge_test.go b/authbridge/authlib/plugins/ibac/judge_test.go index cd7111d5d..bcd73aced 100644 --- a/authbridge/authlib/plugins/ibac/judge_test.go +++ b/authbridge/authlib/plugins/ibac/judge_test.go @@ -10,7 +10,7 @@ import ( "testing" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/llmclient" + "github.com/rossoctl/rossocortex/authbridge/authlib/llmclient" ) // These tests cover the IBAC-specific layer on top of llmclient: diff --git a/authbridge/authlib/plugins/ibac/plugin.go b/authbridge/authlib/plugins/ibac/plugin.go index a237fcad5..9f887e24a 100644 --- a/authbridge/authlib/plugins/ibac/plugin.go +++ b/authbridge/authlib/plugins/ibac/plugin.go @@ -35,10 +35,10 @@ import ( "strings" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/bypass" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/contracts" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins" + "github.com/rossoctl/rossocortex/authbridge/authlib/bypass" + "github.com/rossoctl/rossocortex/authbridge/authlib/contracts" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins" ) // ibacConfig is the plugin's local config schema. See @@ -132,7 +132,7 @@ type ibacConfig struct { } // ConfigSchema exposes the ibacConfig fields for schema-aware tooling -// (abctl edit templates, future kagenti-UI forms, etc.). Implements +// (abctl edit templates, future rossoctl-UI forms, etc.). Implements // pipeline.SchemaProvider; absence would simply make IBAC opaque to // such tooling without affecting runtime. func (p *IBAC) ConfigSchema() []pipeline.FieldSchema { diff --git a/authbridge/authlib/plugins/ibac/plugin_test.go b/authbridge/authlib/plugins/ibac/plugin_test.go index b532adc2c..2a1920147 100644 --- a/authbridge/authlib/plugins/ibac/plugin_test.go +++ b/authbridge/authlib/plugins/ibac/plugin_test.go @@ -9,7 +9,7 @@ import ( "strings" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // fakeJudge records what it was asked and returns the configured @@ -261,7 +261,7 @@ func TestOnRequest_BypassHost_Default(t *testing.T) { pctx := makePCtx(t) // Default bypass list ships with "keycloak.*" — the agent's // token exchange to the Keycloak service must never be judged. - pctx.Host = "keycloak.kagenti" + pctx.Host = "keycloak.rossoctl" action := invokeOnRequest(p, pctx) if action.Type != pipeline.Continue { diff --git a/authbridge/authlib/plugins/inferenceparser/anthropic.go b/authbridge/authlib/plugins/inferenceparser/anthropic.go index 663b6fcc6..76b91a089 100644 --- a/authbridge/authlib/plugins/inferenceparser/anthropic.go +++ b/authbridge/authlib/plugins/inferenceparser/anthropic.go @@ -5,7 +5,7 @@ import ( "encoding/json" "strings" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // anthropicMessagesPath is the Anthropic Messages API endpoint. Clients diff --git a/authbridge/authlib/plugins/inferenceparser/anthropic_test.go b/authbridge/authlib/plugins/inferenceparser/anthropic_test.go index 3ebb97a32..e06f92bd9 100644 --- a/authbridge/authlib/plugins/inferenceparser/anthropic_test.go +++ b/authbridge/authlib/plugins/inferenceparser/anthropic_test.go @@ -4,7 +4,7 @@ import ( "context" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) func TestInferenceParser_AnthropicMessages_Request(t *testing.T) { diff --git a/authbridge/authlib/plugins/inferenceparser/plugin.go b/authbridge/authlib/plugins/inferenceparser/plugin.go index b6153144b..699d06bdf 100644 --- a/authbridge/authlib/plugins/inferenceparser/plugin.go +++ b/authbridge/authlib/plugins/inferenceparser/plugin.go @@ -7,9 +7,9 @@ import ( "log/slog" "strings" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/internal/parsercommon" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/internal/parsercommon" ) // InferenceParser parses outbound OpenAI-compatible LLM inference requests diff --git a/authbridge/authlib/plugins/inferenceparser/plugin_test.go b/authbridge/authlib/plugins/inferenceparser/plugin_test.go index b9e961b6c..070e374e0 100644 --- a/authbridge/authlib/plugins/inferenceparser/plugin_test.go +++ b/authbridge/authlib/plugins/inferenceparser/plugin_test.go @@ -4,7 +4,7 @@ import ( "context" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) func TestInferenceParser_Capabilities(t *testing.T) { diff --git a/authbridge/authlib/plugins/inferenceparser/streaming_test.go b/authbridge/authlib/plugins/inferenceparser/streaming_test.go index 8957241c4..9df1f7e2c 100644 --- a/authbridge/authlib/plugins/inferenceparser/streaming_test.go +++ b/authbridge/authlib/plugins/inferenceparser/streaming_test.go @@ -4,7 +4,7 @@ import ( "context" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) func TestInferenceParser_OnResponseFrame_StreamFoldsDeltas(t *testing.T) { diff --git a/authbridge/authlib/plugins/jwtvalidation/e2e_audiences_test.go b/authbridge/authlib/plugins/jwtvalidation/e2e_audiences_test.go index 4655cb3b4..7e84db9c6 100644 --- a/authbridge/authlib/plugins/jwtvalidation/e2e_audiences_test.go +++ b/authbridge/authlib/plugins/jwtvalidation/e2e_audiences_test.go @@ -13,7 +13,7 @@ import ( "github.com/lestrrat-go/jwx/v2/jwk" "github.com/lestrrat-go/jwx/v2/jwt" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // E2E-style test: full jwt-validation Configure + OnRequest against a diff --git a/authbridge/authlib/plugins/jwtvalidation/identity.go b/authbridge/authlib/plugins/jwtvalidation/identity.go index 7ecac1f9f..82fbd50c7 100644 --- a/authbridge/authlib/plugins/jwtvalidation/identity.go +++ b/authbridge/authlib/plugins/jwtvalidation/identity.go @@ -4,8 +4,8 @@ import ( "strconv" "strings" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/contracts" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/jwtvalidation/validation" + "github.com/rossoctl/rossocortex/authbridge/authlib/contracts" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/jwtvalidation/validation" ) // claimsIdentity adapts a *validation.Claims to the pipeline.Identity diff --git a/authbridge/authlib/plugins/jwtvalidation/identity_test.go b/authbridge/authlib/plugins/jwtvalidation/identity_test.go index a5acc7aab..bb1dad624 100644 --- a/authbridge/authlib/plugins/jwtvalidation/identity_test.go +++ b/authbridge/authlib/plugins/jwtvalidation/identity_test.go @@ -5,8 +5,8 @@ import ( "testing" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/contracts" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/jwtvalidation/validation" + "github.com/rossoctl/rossocortex/authbridge/authlib/contracts" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/jwtvalidation/validation" ) func TestClaimsIdentity_BasicAccessors(t *testing.T) { @@ -30,7 +30,7 @@ func TestClaimsIdentity_ClaimsCarrier(t *testing.T) { // Compile-time + runtime: the adapter is a ClaimsCarrier. var cc contracts.ClaimsCarrier = claimsIdentity{c: &validation.Claims{ Subject: "alice", - Issuer: "https://kc/realms/kagenti", + Issuer: "https://kc/realms/rossoctl", Audience: []string{"hr-agent", "github-tool"}, ExpiresAt: time.Unix(1893456000, 0), }} @@ -38,7 +38,7 @@ func TestClaimsIdentity_ClaimsCarrier(t *testing.T) { if cc.AuthMethod() != "jwt" { t.Errorf("AuthMethod = %q, want jwt", cc.AuthMethod()) } - if cc.Issuer() != "https://kc/realms/kagenti" { + if cc.Issuer() != "https://kc/realms/rossoctl" { t.Errorf("Issuer = %q", cc.Issuer()) } if !reflect.DeepEqual(cc.Audience(), []string{"hr-agent", "github-tool"}) { @@ -47,7 +47,7 @@ func TestClaimsIdentity_ClaimsCarrier(t *testing.T) { claims := cc.Claims() want := map[string]string{ - "issuer": "https://kc/realms/kagenti", + "issuer": "https://kc/realms/rossoctl", "audience": "hr-agent,github-tool", "exp": "1893456000", } diff --git a/authbridge/authlib/plugins/jwtvalidation/placeholder_test.go b/authbridge/authlib/plugins/jwtvalidation/placeholder_test.go index 5f55d0563..ace753dc6 100644 --- a/authbridge/authlib/plugins/jwtvalidation/placeholder_test.go +++ b/authbridge/authlib/plugins/jwtvalidation/placeholder_test.go @@ -5,9 +5,9 @@ import ( "testing" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/placeholder" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/shared" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/placeholder" + "github.com/rossoctl/rossocortex/authbridge/authlib/shared" ) func mintTestContext(store pipeline.SharedStore) *pipeline.Context { diff --git a/authbridge/authlib/plugins/jwtvalidation/plugin.go b/authbridge/authlib/plugins/jwtvalidation/plugin.go index 6270acefd..3d4c603e5 100644 --- a/authbridge/authlib/plugins/jwtvalidation/plugin.go +++ b/authbridge/authlib/plugins/jwtvalidation/plugin.go @@ -11,14 +11,14 @@ import ( "sync/atomic" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/auth" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/bypass" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/config" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/placeholder" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/jwtvalidation/validation" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/routing" + "github.com/rossoctl/rossocortex/authbridge/authlib/auth" + "github.com/rossoctl/rossocortex/authbridge/authlib/bypass" + "github.com/rossoctl/rossocortex/authbridge/authlib/config" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/placeholder" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/jwtvalidation/validation" + "github.com/rossoctl/rossocortex/authbridge/authlib/routing" ) // jwtValidationConfig is the plugin's local config schema. See @@ -125,7 +125,7 @@ func (c *jwtValidationConfig) applyDefaults() { c.AudienceMode = "static" } // When neither Audience nor AudienceFile is set, fall back to the - // Kagenti convention: client-registration writes the agent's client + // Rossoctl convention: client-registration writes the agent's client // ID (which doubles as the inbound audience) to this path. // Deployments that don't run client-registration should set // Audience explicitly — the Configure-time read is best-effort and @@ -248,7 +248,7 @@ func (p *JWTValidation) Configure(raw json.RawMessage) error { } // Capture whether audience_file arrived explicitly so the boot-time // WARN can distinguish "operator pointed at the wrong path" from - // "defaulted to the Kagenti convention and you might not have + // "defaulted to the Rossoctl convention and you might not have // noticed." applyDefaults fills AudienceFile in when both audience // and audience_file are empty, erasing the signal. audienceFileExplicit := c.AudienceFile != "" @@ -271,15 +271,15 @@ func (p *JWTValidation) Configure(raw json.RawMessage) error { // of the initial pod instead of chasing 503s from traffic // that arrived before Init's poll filled the audience in. // When the path was defaulted (not written in the YAML), - // spell that out so non-Kagenti deployers don't wonder why + // spell that out so non-Rossoctl deployers don't wonder why // the plugin is asking for /shared/client-id.txt. if audienceFileExplicit { slog.Warn("jwt-validation: audience_file not yet readable; Init will poll in background", "path", c.AudienceFile, "error", err) } else { - slog.Warn("jwt-validation: audience_file defaulted to Kagenti convention and not yet readable; "+ + slog.Warn("jwt-validation: audience_file defaulted to Rossoctl convention and not yet readable; "+ "Init will poll in background. Set audience (literal value) or audience_file (explicit path) "+ - "if you are not running under Kagenti.", + "if you are not running under Rossoctl.", "path", c.AudienceFile, "error", err) } } diff --git a/authbridge/authlib/plugins/jwtvalidation/plugin_test.go b/authbridge/authlib/plugins/jwtvalidation/plugin_test.go index 4069c349c..704c32d7a 100644 --- a/authbridge/authlib/plugins/jwtvalidation/plugin_test.go +++ b/authbridge/authlib/plugins/jwtvalidation/plugin_test.go @@ -8,10 +8,10 @@ import ( "slices" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/auth" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/bypass" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/jwtvalidation/validation" + "github.com/rossoctl/rossocortex/authbridge/authlib/auth" + "github.com/rossoctl/rossocortex/authbridge/authlib/bypass" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/jwtvalidation/validation" ) // invokeOnRequest mirrors what Pipeline.Run does around each plugin @@ -82,10 +82,10 @@ func TestJWTValidation_Configure_InlineAudienceSuppressesFileDefault(t *testing. func TestJWTValidation_Configure_DefaultsJWKSFromIssuer(t *testing.T) { p := NewJWTValidation() - if err := p.Configure([]byte(`{"issuer":"http://keycloak/realms/kagenti","audience":"a"}`)); err != nil { + if err := p.Configure([]byte(`{"issuer":"http://keycloak/realms/rossoctl","audience":"a"}`)); err != nil { t.Fatalf("Configure: %v", err) } - if got, want := p.cfg.JWKSURL, "http://keycloak/realms/kagenti/protocol/openid-connect/certs"; got != want { + if got, want := p.cfg.JWKSURL, "http://keycloak/realms/rossoctl/protocol/openid-connect/certs"; got != want { t.Errorf("JWKSURL = %q, want %q", got, want) } if p.inner == nil { @@ -96,15 +96,15 @@ func TestJWTValidation_Configure_DefaultsJWKSFromIssuer(t *testing.T) { func TestJWTValidation_Configure_DerivesJWKSFromInternalKeycloakURL(t *testing.T) { p := NewJWTValidation() raw := []byte(`{ - "issuer": "http://keycloak.localtest.me:8080/realms/kagenti", + "issuer": "http://keycloak.localtest.me:8080/realms/rossoctl", "keycloak_url": "http://keycloak-service.keycloak.svc:8080", - "keycloak_realm": "kagenti", + "keycloak_realm": "rossoctl", "audience": "a" }`) if err := p.Configure(raw); err != nil { t.Fatalf("Configure: %v", err) } - want := "http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/certs" + want := "http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/certs" if got := p.cfg.JWKSURL; got != want { t.Errorf("JWKSURL = %q, want %q (internal URL from keycloak_url+realm, not issuer)", got, want) } @@ -113,10 +113,10 @@ func TestJWTValidation_Configure_DerivesJWKSFromInternalKeycloakURL(t *testing.T func TestJWTValidation_Configure_ExplicitJWKSURLWins(t *testing.T) { p := NewJWTValidation() raw := []byte(`{ - "issuer": "http://keycloak.public:8080/realms/kagenti", + "issuer": "http://keycloak.public:8080/realms/rossoctl", "jwks_url": "http://custom-jwks-proxy.example/keys", "keycloak_url": "http://keycloak-internal:8080", - "keycloak_realm": "kagenti", + "keycloak_realm": "rossoctl", "audience": "a" }`) if err := p.Configure(raw); err != nil { @@ -129,10 +129,10 @@ func TestJWTValidation_Configure_ExplicitJWKSURLWins(t *testing.T) { func TestJWTValidation_Configure_PartialKeycloakConfigFallsThroughToIssuer(t *testing.T) { cases := []struct{ name, raw string }{ - {"keycloak_url without realm", `{"issuer":"http://keycloak/realms/kagenti","keycloak_url":"http://internal:8080","audience":"a"}`}, - {"keycloak_realm without url", `{"issuer":"http://keycloak/realms/kagenti","keycloak_realm":"kagenti","audience":"a"}`}, + {"keycloak_url without realm", `{"issuer":"http://keycloak/realms/rossoctl","keycloak_url":"http://internal:8080","audience":"a"}`}, + {"keycloak_realm without url", `{"issuer":"http://keycloak/realms/rossoctl","keycloak_realm":"rossoctl","audience":"a"}`}, } - want := "http://keycloak/realms/kagenti/protocol/openid-connect/certs" + want := "http://keycloak/realms/rossoctl/protocol/openid-connect/certs" for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { p := NewJWTValidation() diff --git a/authbridge/authlib/plugins/litellm_budgettrack/plugin.go b/authbridge/authlib/plugins/litellm_budgettrack/plugin.go index 9cc13b941..49becff21 100644 --- a/authbridge/authlib/plugins/litellm_budgettrack/plugin.go +++ b/authbridge/authlib/plugins/litellm_budgettrack/plugin.go @@ -13,8 +13,8 @@ import ( "sync" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins" ) type budgetTrackConfig struct { diff --git a/authbridge/authlib/plugins/mcpparser/plugin.go b/authbridge/authlib/plugins/mcpparser/plugin.go index 66503e676..c8763ef2a 100644 --- a/authbridge/authlib/plugins/mcpparser/plugin.go +++ b/authbridge/authlib/plugins/mcpparser/plugin.go @@ -7,10 +7,10 @@ import ( "fmt" "log/slog" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/bypass" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/internal/parsercommon" + "github.com/rossoctl/rossocortex/authbridge/authlib/bypass" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/internal/parsercommon" ) // Synthetic method names emitted on body-less MCP transport-layer diff --git a/authbridge/authlib/plugins/mcpparser/plugin_test.go b/authbridge/authlib/plugins/mcpparser/plugin_test.go index 16eca3889..51bd62817 100644 --- a/authbridge/authlib/plugins/mcpparser/plugin_test.go +++ b/authbridge/authlib/plugins/mcpparser/plugin_test.go @@ -7,7 +7,7 @@ import ( "strings" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // configured returns an MCPParser with paths configured. Most existing diff --git a/authbridge/authlib/plugins/mcpparser/streaming_test.go b/authbridge/authlib/plugins/mcpparser/streaming_test.go index fb58548c0..a08435a0d 100644 --- a/authbridge/authlib/plugins/mcpparser/streaming_test.go +++ b/authbridge/authlib/plugins/mcpparser/streaming_test.go @@ -4,7 +4,7 @@ import ( "context" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) func TestMCPParser_OnResponseFrame_PerMessageRecording(t *testing.T) { diff --git a/authbridge/authlib/plugins/opa/README.md b/authbridge/authlib/plugins/opa/README.md index 62e9e2572..c301eb7a5 100644 --- a/authbridge/authlib/plugins/opa/README.md +++ b/authbridge/authlib/plugins/opa/README.md @@ -1,13 +1,13 @@ # opa OPA (Open Policy Agent) plugin for AuthBridge. Downloads policy bundles from a -Kagenti Bundle Server based on the agent's identity and evaluates requests and +Rossoctl Bundle Server based on the agent's identity and evaluates requests and responses against the loaded policy using four fixed decision paths. ## How it works 1. At startup the plugin reads the agent's client ID from `/shared/client-id.txt` - (mounted by the kagenti-operator from a Keycloak-credentials Secret). + (mounted by the operator from a Keycloak-credentials Secret). 2. It creates an embedded OPA engine via the OPA Go SDK and configures it to fetch `bundles?spiffe=` from the bundle server. 3. The SDK downloads the bundle, activates the policy, and begins periodic @@ -52,12 +52,12 @@ pipeline: config: { ... } - name: opa config: - bundle_url: "http://bundle-server.kagenti.svc:8080" + bundle_url: "http://bundle-server.rossoctl.svc:8080" outbound: plugins: - name: opa config: - bundle_url: "http://bundle-server.kagenti.svc:8080" + bundle_url: "http://bundle-server.rossoctl.svc:8080" - name: token-exchange config: { ... } ``` @@ -74,7 +74,7 @@ containing sensitive keywords), extend the input with `a2a.content`: ```yaml - name: opa config: - bundle_url: "http://bundle-server.kagenti.svc:8080" + bundle_url: "http://bundle-server.rossoctl.svc:8080" include: - "a2a.content" ``` @@ -90,7 +90,7 @@ the full conversation history: ```yaml - name: opa config: - bundle_url: "http://bundle-server.kagenti.svc:8080" + bundle_url: "http://bundle-server.rossoctl.svc:8080" include: - "mcp.params" # full tool arguments (not just name/uri) - "mcp.result" # tool response data (response path) @@ -110,7 +110,7 @@ Additionally a future enhancement will add TLS with service account token. | Field | Required | Default | Description | |---|---|---|---| -| `bundle_url` | yes | | Base URL of the Kagenti Bundle Server (HTTP, in-cluster) | +| `bundle_url` | yes | | Base URL of the Rossoctl Bundle Server (HTTP, in-cluster) | | `agent_id_file` | no | `/shared/client-id.txt` | Path to the file containing the agent's client ID | | `agent_id` | no | | Inline agent ID; when set, `agent_id_file` is ignored | | `polling_min_delay` | no | `10` | Minimum bundle polling interval in seconds | diff --git a/authbridge/authlib/plugins/opa/plugin.go b/authbridge/authlib/plugins/opa/plugin.go index fe475b2f8..b44512fb2 100644 --- a/authbridge/authlib/plugins/opa/plugin.go +++ b/authbridge/authlib/plugins/opa/plugin.go @@ -17,9 +17,9 @@ import ( "github.com/open-policy-agent/opa/sdk" opalog "github.com/open-policy-agent/opa/v1/logging" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/config" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins" + "github.com/rossoctl/rossocortex/authbridge/authlib/config" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins" ) const ( @@ -171,7 +171,7 @@ var ( singleton *sharedSDK ) -// OPA evaluates requests against OPA bundles downloaded from a Kagenti +// OPA evaluates requests against OPA bundles downloaded from a Rossoctl // Bundle Server. The bundle resource path is derived from the agent's // identity (/shared/client-id.txt). type OPA struct { @@ -221,8 +221,8 @@ func (p *OPA) Configure(raw json.RawMessage) error { slog.Warn("opa: agent_id_file not yet readable; Init will poll in background", "path", c.AgentIDFile, "error", err) } else { - slog.Warn("opa: agent_id_file defaulted to Kagenti convention and not yet readable; "+ - "Init will poll in background. Set agent_id or agent_id_file if not running under Kagenti.", + slog.Warn("opa: agent_id_file defaulted to Rossoctl convention and not yet readable; "+ + "Init will poll in background. Set agent_id or agent_id_file if not running under Rossoctl.", "path", c.AgentIDFile, "error", err) } } @@ -352,13 +352,13 @@ func (p *OPA) buildOPAConfig() ([]byte, string, error) { cfg := map[string]any{ "services": map[string]any{ - "kagenti": map[string]any{ + "rossoctl": map[string]any{ "url": p.cfg.BundleURL, }, }, "bundles": map[string]any{ "authz": map[string]any{ - "service": "kagenti", + "service": "rossoctl", "resource": fmt.Sprintf("bundles?spiffe=%s", escapedSPIFFEID), "polling": map[string]any{ "min_delay_seconds": p.cfg.PollingMinDelay, diff --git a/authbridge/authlib/plugins/opa/plugin_test.go b/authbridge/authlib/plugins/opa/plugin_test.go index 00750c1bd..8b7d11522 100644 --- a/authbridge/authlib/plugins/opa/plugin_test.go +++ b/authbridge/authlib/plugins/opa/plugin_test.go @@ -9,7 +9,7 @@ import ( "github.com/open-policy-agent/opa/sdk" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // mockDecider implements the decider interface for testing. @@ -1144,9 +1144,9 @@ func TestBuildOPAConfig(t *testing.T) { t.Fatalf("invalid JSON: %v", err) } services := cfg["services"].(map[string]any) - kagenti := services["kagenti"].(map[string]any) - if kagenti["url"] != "http://bundle-server:8080" { - t.Errorf("expected bundle URL, got %v", kagenti["url"]) + rossoctl := services["rossoctl"].(map[string]any) + if rossoctl["url"] != "http://bundle-server:8080" { + t.Errorf("expected bundle URL, got %v", rossoctl["url"]) } bundles := cfg["bundles"].(map[string]any) authz := bundles["authz"].(map[string]any) diff --git a/authbridge/authlib/plugins/plugins_test.go b/authbridge/authlib/plugins/plugins_test.go index 1e8ebac82..db465accb 100644 --- a/authbridge/authlib/plugins/plugins_test.go +++ b/authbridge/authlib/plugins/plugins_test.go @@ -6,20 +6,20 @@ import ( "strings" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/config" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins" + "github.com/rossoctl/rossocortex/authbridge/authlib/config" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins" // Side-effect imports register the bundled plugins. Same pattern // main.go uses — each plugin lives in its own subpackage and // advertises itself via init(); importing here makes the name // resolvable to plugins.Build in these tests. - _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/a2aparser" - _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/inferenceparser" - jwtvalidation "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/jwtvalidation" - _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/mcpparser" - _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/opa" - _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/tokenbroker" - tokenexchange "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/tokenexchange" + _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/a2aparser" + _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/inferenceparser" + jwtvalidation "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/jwtvalidation" + _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/mcpparser" + _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/opa" + _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/tokenbroker" + tokenexchange "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/tokenexchange" ) // TestBuiltinsRegistered verifies every in-tree plugin is discoverable diff --git a/authbridge/authlib/plugins/plugintesting/plugintesting.go b/authbridge/authlib/plugins/plugintesting/plugintesting.go index ea2527b2b..c4149b135 100644 --- a/authbridge/authlib/plugins/plugintesting/plugintesting.go +++ b/authbridge/authlib/plugins/plugintesting/plugintesting.go @@ -16,9 +16,9 @@ import ( "context" "net/http" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/auth" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/routing" + "github.com/rossoctl/rossocortex/authbridge/authlib/auth" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/routing" ) // JWTValidationStub mimics the jwt-validation plugin's OnRequest diff --git a/authbridge/authlib/plugins/registry.go b/authbridge/authlib/plugins/registry.go index 85e401ea9..2eec91bf4 100644 --- a/authbridge/authlib/plugins/registry.go +++ b/authbridge/authlib/plugins/registry.go @@ -6,9 +6,9 @@ import ( "strings" "sync" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/config" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/spiffe" + "github.com/rossoctl/rossocortex/authbridge/authlib/config" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/spiffe" ) // PluginFactory returns a fresh plugin instance. Plugins take no @@ -41,7 +41,7 @@ var ( // registration, log/slog handler registration): plugins live in their // own package and advertise themselves by side-effect import: // -// import _ "github.com/acme/kagenti-rate-limiter/ratelimit" +// import _ "github.com/acme/rossoctl-rate-limiter/ratelimit" // // Double-registration under the same name panics. Silent last-write- // wins would let a version mismatch or deployment bug poison the diff --git a/authbridge/authlib/plugins/registry_test.go b/authbridge/authlib/plugins/registry_test.go index c203be3c2..44489dada 100644 --- a/authbridge/authlib/plugins/registry_test.go +++ b/authbridge/authlib/plugins/registry_test.go @@ -6,9 +6,9 @@ import ( "reflect" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/config" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/spiffe" + "github.com/rossoctl/rossocortex/authbridge/authlib/config" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/spiffe" ) // TestRegisterPlugin_DoubleRegistration_Panics locks the strict-fail diff --git a/authbridge/authlib/plugins/sparc/collect.go b/authbridge/authlib/plugins/sparc/collect.go index 5c66c29de..88f070682 100644 --- a/authbridge/authlib/plugins/sparc/collect.go +++ b/authbridge/authlib/plugins/sparc/collect.go @@ -6,7 +6,7 @@ import ( "path" "strings" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // correlateInferenceContext pulls the conversation (incl. system prompt) and diff --git a/authbridge/authlib/plugins/sparc/plugin.go b/authbridge/authlib/plugins/sparc/plugin.go index 012ded3f9..db3c79f02 100644 --- a/authbridge/authlib/plugins/sparc/plugin.go +++ b/authbridge/authlib/plugins/sparc/plugin.go @@ -6,7 +6,7 @@ // available tool specifications. SPARC catches hallucinated / ungrounded // arguments (e.g. an invented transaction id) and inappropriate tool selection. // -// Generic by design — works for ANY kagenti agent. SPARC's three inputs are +// Generic by design — works for ANY rossoctl agent. SPARC's three inputs are // collected from exactly what the agent produces, with no bespoke per-agent // wiring: // @@ -21,7 +21,7 @@ // Enforcement is format-aware (the verdict is returned to the agent in the // shape it expects): // -// - enforcement: "mcp" (default; the kagenti norm) — gate the outbound MCP +// - enforcement: "mcp" (default; the rossoctl norm) — gate the outbound MCP // tools/call. On a reflected reject, return SPARC's clarification as a // JSON-RPC MCP tool *result*; the agent's MCP client consumes it like any // tool output and asks the user for the missing detail. Robust to LLM @@ -45,9 +45,9 @@ import ( "strings" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/bypass" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins" + "github.com/rossoctl/rossocortex/authbridge/authlib/bypass" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins" ) // enforcement modes. diff --git a/authbridge/authlib/plugins/sparc/plugin_test.go b/authbridge/authlib/plugins/sparc/plugin_test.go index ee8414fbe..cdfe717da 100644 --- a/authbridge/authlib/plugins/sparc/plugin_test.go +++ b/authbridge/authlib/plugins/sparc/plugin_test.go @@ -6,7 +6,7 @@ import ( "net/http" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) type fakeReflector struct { diff --git a/authbridge/authlib/plugins/sparc/respond.go b/authbridge/authlib/plugins/sparc/respond.go index 7cfaaca5d..01db5b278 100644 --- a/authbridge/authlib/plugins/sparc/respond.go +++ b/authbridge/authlib/plugins/sparc/respond.go @@ -5,7 +5,7 @@ import ( "fmt" "strings" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // buildClarificationText renders an agent-facing message from SPARC's issues. diff --git a/authbridge/authlib/plugins/staticinject/plugin.go b/authbridge/authlib/plugins/staticinject/plugin.go index 08a897688..b8041c297 100644 --- a/authbridge/authlib/plugins/staticinject/plugin.go +++ b/authbridge/authlib/plugins/staticinject/plugin.go @@ -7,9 +7,9 @@ import ( "fmt" "strings" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/auth" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins" + "github.com/rossoctl/rossocortex/authbridge/authlib/auth" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins" ) // Source values for staticInjectConfig.Source. diff --git a/authbridge/authlib/plugins/staticinject/plugin_test.go b/authbridge/authlib/plugins/staticinject/plugin_test.go index 6623d3f26..21a6915ce 100644 --- a/authbridge/authlib/plugins/staticinject/plugin_test.go +++ b/authbridge/authlib/plugins/staticinject/plugin_test.go @@ -9,7 +9,7 @@ import ( "strings" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) func TestSwapsPlaceholderForRealToken(t *testing.T) { diff --git a/authbridge/authlib/plugins/staticinject/resolver.go b/authbridge/authlib/plugins/staticinject/resolver.go index 5baa1e259..d01964114 100644 --- a/authbridge/authlib/plugins/staticinject/resolver.go +++ b/authbridge/authlib/plugins/staticinject/resolver.go @@ -11,7 +11,7 @@ import ( "net/http" "path/filepath" - credconfig "github.com/kagenti/kagenti-extensions/authbridge/authlib/config" + credconfig "github.com/rossoctl/rossocortex/authbridge/authlib/config" ) // Resolver looks up a credential value by key. ok=false means the key is diff --git a/authbridge/authlib/plugins/stats.go b/authbridge/authlib/plugins/stats.go index 86fb1694c..1731ad462 100644 --- a/authbridge/authlib/plugins/stats.go +++ b/authbridge/authlib/plugins/stats.go @@ -1,8 +1,8 @@ package plugins import ( - "github.com/kagenti/kagenti-extensions/authbridge/authlib/auth" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/auth" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // StatsSource is an optional interface a plugin implements when it diff --git a/authbridge/authlib/plugins/tokenbroker/plugin.go b/authbridge/authlib/plugins/tokenbroker/plugin.go index 1aef883f9..8066b4633 100644 --- a/authbridge/authlib/plugins/tokenbroker/plugin.go +++ b/authbridge/authlib/plugins/tokenbroker/plugin.go @@ -13,10 +13,10 @@ import ( "strings" "github.com/gobwas/glob" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/auth" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/tokenbroker/client" + "github.com/rossoctl/rossocortex/authbridge/authlib/auth" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/tokenbroker/client" "gopkg.in/yaml.v3" ) diff --git a/authbridge/authlib/plugins/tokenbroker/plugin_edge_test.go b/authbridge/authlib/plugins/tokenbroker/plugin_edge_test.go index 0382c9aeb..bf8a0f3e6 100644 --- a/authbridge/authlib/plugins/tokenbroker/plugin_edge_test.go +++ b/authbridge/authlib/plugins/tokenbroker/plugin_edge_test.go @@ -10,8 +10,8 @@ import ( "testing" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/auth" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/auth" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // ============================================================================= diff --git a/authbridge/authlib/plugins/tokenbroker/plugin_request_test.go b/authbridge/authlib/plugins/tokenbroker/plugin_request_test.go index 683402f20..f1cb70afb 100644 --- a/authbridge/authlib/plugins/tokenbroker/plugin_request_test.go +++ b/authbridge/authlib/plugins/tokenbroker/plugin_request_test.go @@ -7,7 +7,7 @@ import ( "net/http/httptest" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // ============================================================================= diff --git a/authbridge/authlib/plugins/tokenbroker/plugin_routing_test.go b/authbridge/authlib/plugins/tokenbroker/plugin_routing_test.go index 197974757..9a8d372fd 100644 --- a/authbridge/authlib/plugins/tokenbroker/plugin_routing_test.go +++ b/authbridge/authlib/plugins/tokenbroker/plugin_routing_test.go @@ -7,7 +7,7 @@ import ( "net/http/httptest" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // ============================================================================= diff --git a/authbridge/authlib/plugins/tokenexchange/delegation_test.go b/authbridge/authlib/plugins/tokenexchange/delegation_test.go index 066059cf6..4861f7a7c 100644 --- a/authbridge/authlib/plugins/tokenexchange/delegation_test.go +++ b/authbridge/authlib/plugins/tokenexchange/delegation_test.go @@ -4,8 +4,8 @@ import ( "reflect" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/auth" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/auth" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) func TestSplitScopes(t *testing.T) { diff --git a/authbridge/authlib/plugins/tokenexchange/placeholder_test.go b/authbridge/authlib/plugins/tokenexchange/placeholder_test.go index f15d19c89..00f4b7aff 100644 --- a/authbridge/authlib/plugins/tokenexchange/placeholder_test.go +++ b/authbridge/authlib/plugins/tokenexchange/placeholder_test.go @@ -7,9 +7,9 @@ import ( "testing" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/placeholder" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/shared" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/placeholder" + "github.com/rossoctl/rossocortex/authbridge/authlib/shared" ) func resolveTestPlugin(t *testing.T, exchangeURL string) *TokenExchange { diff --git a/authbridge/authlib/plugins/tokenexchange/plugin.go b/authbridge/authlib/plugins/tokenexchange/plugin.go index 0d0337133..708293e53 100644 --- a/authbridge/authlib/plugins/tokenexchange/plugin.go +++ b/authbridge/authlib/plugins/tokenexchange/plugin.go @@ -12,15 +12,15 @@ import ( "sync/atomic" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/auth" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/config" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/placeholder" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/tokenexchange/cache" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/tokenexchange/exchange" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/routing" - fwspiffe "github.com/kagenti/kagenti-extensions/authbridge/authlib/spiffe" + "github.com/rossoctl/rossocortex/authbridge/authlib/auth" + "github.com/rossoctl/rossocortex/authbridge/authlib/config" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/placeholder" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/tokenexchange/cache" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/tokenexchange/exchange" + "github.com/rossoctl/rossocortex/authbridge/authlib/routing" + fwspiffe "github.com/rossoctl/rossocortex/authbridge/authlib/spiffe" ) // tokenExchangeConfig is the plugin's local config schema. See @@ -50,7 +50,7 @@ type tokenExchangeConfig struct { ProviderURL string `json:"provider_url" description:"IdP base URL for endpoint derivation. Interpretation varies by provider."` // ProviderRealm is the IdP-specific namespace/tenant: - // keycloak: realm name (e.g. kagenti) + // keycloak: realm name (e.g. rossoctl) // entra-id: tenant ID or domain (e.g. contoso.onmicrosoft.com) // okta: authorization server ID (optional, omit for org-level) ProviderRealm string `json:"provider_realm" description:"IdP-specific realm/tenant/auth-server. Keycloak: realm name. Entra ID: tenant ID. Okta: auth server ID (optional)."` @@ -176,7 +176,7 @@ func (c *tokenExchangeConfig) applyDefaults() { if c.NoTokenPolicy == "" { c.NoTokenPolicy = auth.NoTokenPolicyDeny } - // Kagenti file-system conventions for credential sources. Each + // Rossoctl file-system conventions for credential sources. Each // default kicks in only when the matching inline value is also // empty, so operators who supply inline credentials are never // surprised by a file read. diff --git a/authbridge/authlib/plugins/tokenexchange/plugin_test.go b/authbridge/authlib/plugins/tokenexchange/plugin_test.go index 632a0a021..9c7e54811 100644 --- a/authbridge/authlib/plugins/tokenexchange/plugin_test.go +++ b/authbridge/authlib/plugins/tokenexchange/plugin_test.go @@ -7,8 +7,8 @@ import ( "net/http/httptest" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - fwspiffe "github.com/kagenti/kagenti-extensions/authbridge/authlib/spiffe" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + fwspiffe "github.com/rossoctl/rossocortex/authbridge/authlib/spiffe" ) // fakeJWTSource is a minimal fwspiffe.JWTSource for unit-testing the @@ -48,13 +48,13 @@ func TestTokenExchange_Configure_DerivesTokenURL(t *testing.T) { p := NewTokenExchange() raw := []byte(`{ "keycloak_url":"http://keycloak:8080", - "keycloak_realm":"kagenti", + "keycloak_realm":"rossoctl", "identity":{"type":"client-secret","client_id":"c","client_secret":"s"} }`) if err := p.Configure(raw); err != nil { t.Fatalf("Configure: %v", err) } - want := "http://keycloak:8080/realms/kagenti/protocol/openid-connect/token" + want := "http://keycloak:8080/realms/rossoctl/protocol/openid-connect/token" if p.cfg.TokenURL != want { t.Errorf("token_url = %q, want %q", p.cfg.TokenURL, want) } diff --git a/authbridge/authlib/plugins/tokenexchange/provider.go b/authbridge/authlib/plugins/tokenexchange/provider.go index 807c1b25f..24d648420 100644 --- a/authbridge/authlib/plugins/tokenexchange/provider.go +++ b/authbridge/authlib/plugins/tokenexchange/provider.go @@ -4,8 +4,8 @@ import ( "fmt" "sync" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/tokenexchange/exchange" - fwspiffe "github.com/kagenti/kagenti-extensions/authbridge/authlib/spiffe" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/tokenexchange/exchange" + fwspiffe "github.com/rossoctl/rossocortex/authbridge/authlib/spiffe" ) // Identity type constants. diff --git a/authbridge/authlib/plugins/tokenexchange/provider_keycloak.go b/authbridge/authlib/plugins/tokenexchange/provider_keycloak.go index b864ce279..dec5df386 100644 --- a/authbridge/authlib/plugins/tokenexchange/provider_keycloak.go +++ b/authbridge/authlib/plugins/tokenexchange/provider_keycloak.go @@ -4,8 +4,8 @@ import ( "errors" "strings" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/tokenexchange/exchange" - fwspiffe "github.com/kagenti/kagenti-extensions/authbridge/authlib/spiffe" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/tokenexchange/exchange" + fwspiffe "github.com/rossoctl/rossocortex/authbridge/authlib/spiffe" ) // keycloakProvider derives endpoints and builds client auth from diff --git a/authbridge/authlib/reloader/reloader.go b/authbridge/authlib/reloader/reloader.go index a159c5bf0..b0553695e 100644 --- a/authbridge/authlib/reloader/reloader.go +++ b/authbridge/authlib/reloader/reloader.go @@ -34,8 +34,8 @@ import ( "github.com/fsnotify/fsnotify" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/config" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/config" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // PipelineBuilder loads the config file, validates it, and returns the diff --git a/authbridge/authlib/reloader/reloader_test.go b/authbridge/authlib/reloader/reloader_test.go index 6c509e50d..eeb3703f9 100644 --- a/authbridge/authlib/reloader/reloader_test.go +++ b/authbridge/authlib/reloader/reloader_test.go @@ -8,8 +8,8 @@ import ( "testing" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/config" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/config" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // buildFn captures the caller-supplied pipeline results so tests can diff --git a/authbridge/authlib/session/intent_pin_test.go b/authbridge/authlib/session/intent_pin_test.go index 4284e20cb..b2e0c5244 100644 --- a/authbridge/authlib/session/intent_pin_test.go +++ b/authbridge/authlib/session/intent_pin_test.go @@ -4,7 +4,7 @@ import ( "testing" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // intent fabricates the same shape SessionView.LastIntent recognizes: diff --git a/authbridge/authlib/session/store.go b/authbridge/authlib/session/store.go index 89288adca..164f7aa8b 100644 --- a/authbridge/authlib/session/store.go +++ b/authbridge/authlib/session/store.go @@ -10,7 +10,7 @@ import ( "sync/atomic" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // DefaultSessionID is used when no explicit A2A SessionID is present and no diff --git a/authbridge/authlib/session/store_test.go b/authbridge/authlib/session/store_test.go index 836791ad1..81e6322c5 100644 --- a/authbridge/authlib/session/store_test.go +++ b/authbridge/authlib/session/store_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) func TestStore_AppendAndView(t *testing.T) { diff --git a/authbridge/authlib/sessionapi/catalog_adapter.go b/authbridge/authlib/sessionapi/catalog_adapter.go index 90d0edf21..52d583c5b 100644 --- a/authbridge/authlib/sessionapi/catalog_adapter.go +++ b/authbridge/authlib/sessionapi/catalog_adapter.go @@ -1,8 +1,8 @@ package sessionapi import ( - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins" ) // PluginsCatalog adapts plugins.Catalog() into the wire-shaped diff --git a/authbridge/authlib/sessionapi/server.go b/authbridge/authlib/sessionapi/server.go index 52deff8ad..2fd6689e5 100644 --- a/authbridge/authlib/sessionapi/server.go +++ b/authbridge/authlib/sessionapi/server.go @@ -17,9 +17,9 @@ import ( "strings" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/redact" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/session" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/redact" + "github.com/rossoctl/rossocortex/authbridge/authlib/session" ) // defaultHeartbeatInterval is how often the SSE stream sends a keep-alive @@ -64,7 +64,7 @@ type CatalogEntry struct { // FieldSchemaEntry is the wire shape for one config field's schema // metadata. Mirrors pipeline.FieldSchema; lives in the sessionapi -// package so consumers (abctl apiclient, future kagenti-UI clients) +// package so consumers (abctl apiclient, future rossoctl-UI clients) // don't have to import authlib/pipeline transitively. type FieldSchemaEntry struct { Name string `json:"name"` diff --git a/authbridge/authlib/sessionapi/server_test.go b/authbridge/authlib/sessionapi/server_test.go index 178e6b293..38e541ac6 100644 --- a/authbridge/authlib/sessionapi/server_test.go +++ b/authbridge/authlib/sessionapi/server_test.go @@ -12,8 +12,8 @@ import ( "testing" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/session" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/session" ) // newTestServer wires a Server backed by a fresh Store onto httptest so tests diff --git a/authbridge/authlib/tls/client.go b/authbridge/authlib/tls/client.go index 19ba89a40..02064b6f3 100644 --- a/authbridge/authlib/tls/client.go +++ b/authbridge/authlib/tls/client.go @@ -5,7 +5,7 @@ import ( "crypto/x509" "fmt" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/spiffe" + "github.com/rossoctl/rossocortex/authbridge/authlib/spiffe" ) // ClientConfig builds an mTLS *tls.Config for the forward-proxy diff --git a/authbridge/authlib/tls/server.go b/authbridge/authlib/tls/server.go index b85e5843a..6add98c9e 100644 --- a/authbridge/authlib/tls/server.go +++ b/authbridge/authlib/tls/server.go @@ -5,7 +5,7 @@ import ( "crypto/x509" "fmt" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/spiffe" + "github.com/rossoctl/rossocortex/authbridge/authlib/spiffe" ) // ServerConfig builds an mTLS *tls.Config for the reverse-proxy diff --git a/authbridge/authlib/tls/server_test.go b/authbridge/authlib/tls/server_test.go index 833019425..dfdc7a909 100644 --- a/authbridge/authlib/tls/server_test.go +++ b/authbridge/authlib/tls/server_test.go @@ -9,8 +9,8 @@ import ( "sync/atomic" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/spiffe" - authtls "github.com/kagenti/kagenti-extensions/authbridge/authlib/tls" + "github.com/rossoctl/rossocortex/authbridge/authlib/spiffe" + authtls "github.com/rossoctl/rossocortex/authbridge/authlib/tls" ) // fakeSource lets tests drive Certificate / TrustBundle results diff --git a/authbridge/cmd/README.md b/authbridge/cmd/README.md index 16957aa57..e379fd54f 100644 --- a/authbridge/cmd/README.md +++ b/authbridge/cmd/README.md @@ -11,9 +11,9 @@ image is a build variant of the proxy binary (proxy Dockerfile + | Directory | Mode | Listeners | Plugins | Image (CI) | |---|---|---|---|---| -| [`authbridge-proxy/`](authbridge-proxy/) | `proxy-sidecar` (default) | HTTP forward + reverse proxies | full (jwt-validation, token-exchange, a2a-parser, mcp-parser, inference-parser) | `ghcr.io/kagenti/kagenti-extensions/authbridge` | -| [`authbridge-envoy/`](authbridge-envoy/) | `envoy-sidecar` | gRPC ext_proc on `:9090` (hooked into Envoy) | full | `ghcr.io/kagenti/kagenti-extensions/authbridge-envoy` | -| `authbridge-lite` _(build variant of `authbridge-proxy`)_ | `proxy-sidecar` | HTTP forward + reverse proxies | lite — `authbridge-proxy` built with `exclude_plugin_*` tags (jwt-validation + token-exchange only; OPA + parsers dropped) | `ghcr.io/kagenti/kagenti-extensions/authbridge-lite` | +| [`authbridge-proxy/`](authbridge-proxy/) | `proxy-sidecar` (default) | HTTP forward + reverse proxies | full (jwt-validation, token-exchange, a2a-parser, mcp-parser, inference-parser) | `ghcr.io/rossoctl/rossocortex/authbridge` | +| [`authbridge-envoy/`](authbridge-envoy/) | `envoy-sidecar` | gRPC ext_proc on `:9090` (hooked into Envoy) | full | `ghcr.io/rossoctl/rossocortex/authbridge-envoy` | +| `authbridge-lite` _(build variant of `authbridge-proxy`)_ | `proxy-sidecar` | HTTP forward + reverse proxies | lite — `authbridge-proxy` built with `exclude_plugin_*` tags (jwt-validation + token-exchange only; OPA + parsers dropped) | `ghcr.io/rossoctl/rossocortex/authbridge-lite` | | [`abctl/`](abctl/) | n/a | n/a | n/a | not published — local TUI for the Session Events API | Each binary directory contains `main.go`, `go.mod`/`go.sum`, diff --git a/authbridge/cmd/abctl/README.md b/authbridge/cmd/abctl/README.md index fefda3476..5b8a45e9e 100644 --- a/authbridge/cmd/abctl/README.md +++ b/authbridge/cmd/abctl/README.md @@ -119,7 +119,7 @@ subtree in `$EDITOR` (or `vi` if unset). On save, abctl shows a diff and asks `apply this change? (y/N)`. Confirming runs `kubectl apply --server-side` against the per-agent ConfigMap with `--field-manager=abctl --force-conflicts=true` (taking ownership of -`data.config.yaml` from the kagenti-operator's webhook on first +`data.config.yaml` from the operator's webhook on first edit), then polls the framework's `/reload/status` until the reload completes (success or failure). @@ -161,7 +161,7 @@ populate it for the rest of the session. The per-agent ConfigMap is named `authbridge-config-`. abctl resolves `` from the selected pod's `app.kubernetes.io/name` -label (kagenti-operator sets this). If the label is absent, abctl +label (operator sets this). If the label is absent, abctl falls back to stripping the last two dash-separated segments of the pod name (the ReplicaSet hash + pod suffix). diff --git a/authbridge/cmd/abctl/apiclient/client.go b/authbridge/cmd/abctl/apiclient/client.go index 4c2fe862f..6a4ff7c32 100644 --- a/authbridge/cmd/abctl/apiclient/client.go +++ b/authbridge/cmd/abctl/apiclient/client.go @@ -12,8 +12,8 @@ import ( "net/url" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/session" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/session" ) // Client is a handle to a session API endpoint. Safe for concurrent use. diff --git a/authbridge/cmd/abctl/apiclient/client_test.go b/authbridge/cmd/abctl/apiclient/client_test.go index 774e3f0e2..1c824acb3 100644 --- a/authbridge/cmd/abctl/apiclient/client_test.go +++ b/authbridge/cmd/abctl/apiclient/client_test.go @@ -8,8 +8,8 @@ import ( "net/http/httptest" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/session" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/session" ) func TestListSessions(t *testing.T) { diff --git a/authbridge/cmd/abctl/apiclient/sse.go b/authbridge/cmd/abctl/apiclient/sse.go index 5da534fde..ac21debf4 100644 --- a/authbridge/cmd/abctl/apiclient/sse.go +++ b/authbridge/cmd/abctl/apiclient/sse.go @@ -12,7 +12,7 @@ import ( "strings" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // StreamEvent is what Stream publishes. One of Event or Status is set per diff --git a/authbridge/cmd/abctl/edit/configmap.go b/authbridge/cmd/abctl/edit/configmap.go index d170b6a13..f16abd2ec 100644 --- a/authbridge/cmd/abctl/edit/configmap.go +++ b/authbridge/cmd/abctl/edit/configmap.go @@ -21,7 +21,7 @@ import ( ) // configMapDataKey is the key inside the ConfigMap's data: mapping that -// holds the runtime YAML. The kagenti-operator and the editor both +// holds the runtime YAML. The operator and the editor both // agree on this name; if a future operator change renames it, all four // callers (Fetch, BuildManifest, the two extractInnerYAML branches) // flip together by changing this constant. @@ -301,7 +301,7 @@ func extractInnerYAML(cmYAML []byte) ([]byte, error) { // Apply writes manifest to a tempfile and runs kubectl apply --server-side // with --force-conflicts=true and a dedicated abctl field-manager. The -// kagenti-operator's webhook owns data.config.yaml on initial creation; +// operator's webhook owns data.config.yaml on initial creation; // the user has explicitly confirmed this edit by pressing "y" at the // diff prompt, so taking field-manager ownership is the intended outcome. // diff --git a/authbridge/cmd/abctl/edit/configmap_test.go b/authbridge/cmd/abctl/edit/configmap_test.go index 55e1c9aaa..74784bea9 100644 --- a/authbridge/cmd/abctl/edit/configmap_test.go +++ b/authbridge/cmd/abctl/edit/configmap_test.go @@ -328,7 +328,7 @@ metadata: creationTimestamp: "2026-05-29T00:00:00Z" generation: 7 managedFields: - - manager: kagenti-webhook + - manager: rossoctl-webhook operation: Apply data: config.yaml: | diff --git a/authbridge/cmd/abctl/edit/edit.go b/authbridge/cmd/abctl/edit/edit.go index db26fc502..6aef73f36 100644 --- a/authbridge/cmd/abctl/edit/edit.go +++ b/authbridge/cmd/abctl/edit/edit.go @@ -8,7 +8,7 @@ import ( tea "github.com/charmbracelet/bubbletea" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/apiclient" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/apiclient" ) // tempFileMaxAge is how long a stale edit tempfile is allowed to sit diff --git a/authbridge/cmd/abctl/edit/templates.go b/authbridge/cmd/abctl/edit/templates.go index 32bca5c27..8dd70abcb 100644 --- a/authbridge/cmd/abctl/edit/templates.go +++ b/authbridge/cmd/abctl/edit/templates.go @@ -5,7 +5,7 @@ import ( "fmt" "strings" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/apiclient" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/apiclient" ) // FenceMarker delimits the active pipeline subtree (above) from the diff --git a/authbridge/cmd/abctl/edit/templates_test.go b/authbridge/cmd/abctl/edit/templates_test.go index 4fb435367..2ad50e95d 100644 --- a/authbridge/cmd/abctl/edit/templates_test.go +++ b/authbridge/cmd/abctl/edit/templates_test.go @@ -8,7 +8,7 @@ import ( "strings" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/apiclient" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/apiclient" ) func TestRenderTemplates_EmptyCatalog(t *testing.T) { diff --git a/authbridge/cmd/abctl/edit/validate.go b/authbridge/cmd/abctl/edit/validate.go index 7792e4725..316be7963 100644 --- a/authbridge/cmd/abctl/edit/validate.go +++ b/authbridge/cmd/abctl/edit/validate.go @@ -5,7 +5,7 @@ import ( "gopkg.in/yaml.v3" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/apiclient" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/apiclient" ) // ValidationError describes one problem with a proposed pipeline, diff --git a/authbridge/cmd/abctl/edit/validate_test.go b/authbridge/cmd/abctl/edit/validate_test.go index 125ca3f1a..61be6502a 100644 --- a/authbridge/cmd/abctl/edit/validate_test.go +++ b/authbridge/cmd/abctl/edit/validate_test.go @@ -4,7 +4,7 @@ import ( "strings" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/apiclient" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/apiclient" ) func validateFixtureCatalog() []apiclient.PluginCatalogEntry { diff --git a/authbridge/cmd/abctl/go.mod b/authbridge/cmd/abctl/go.mod index 5e72c653d..b1fdfb1ff 100644 --- a/authbridge/cmd/abctl/go.mod +++ b/authbridge/cmd/abctl/go.mod @@ -1,4 +1,4 @@ -module github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl +module github.com/rossoctl/rossocortex/authbridge/cmd/abctl go 1.26.4 @@ -7,14 +7,14 @@ go 1.26.4 // workspace will not resolve this path — if abctl is ever distributed as // a standalone binary, drop the replace and version authlib as a proper // dependency once it has a tagged release. -replace github.com/kagenti/kagenti-extensions/authbridge/authlib => ../../authlib +replace github.com/rossoctl/rossocortex/authbridge/authlib => ../../authlib require ( github.com/charmbracelet/bubbles v1.0.0 github.com/charmbracelet/bubbletea v1.3.10 github.com/charmbracelet/lipgloss v1.1.0 github.com/charmbracelet/x/ansi v0.11.7 - github.com/kagenti/kagenti-extensions/authbridge/authlib v0.0.0-00010101000000-000000000000 + github.com/rossoctl/rossocortex/authbridge/authlib v0.0.0-00010101000000-000000000000 gopkg.in/yaml.v3 v3.0.1 ) diff --git a/authbridge/cmd/abctl/main.go b/authbridge/cmd/abctl/main.go index 101202088..f3bd4a2e1 100644 --- a/authbridge/cmd/abctl/main.go +++ b/authbridge/cmd/abctl/main.go @@ -15,9 +15,9 @@ import ( "os/signal" "syscall" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/cluster" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/edit" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/tui" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/cluster" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/edit" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/tui" ) func main() { diff --git a/authbridge/cmd/abctl/tui/app.go b/authbridge/cmd/abctl/tui/app.go index 67904b982..add634aa5 100644 --- a/authbridge/cmd/abctl/tui/app.go +++ b/authbridge/cmd/abctl/tui/app.go @@ -18,11 +18,11 @@ import ( "github.com/charmbracelet/lipgloss" "gopkg.in/yaml.v3" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/session" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/apiclient" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/cluster" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/edit" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/session" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/apiclient" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/cluster" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/edit" ) // Pane identifiers. diff --git a/authbridge/cmd/abctl/tui/catalog_pane.go b/authbridge/cmd/abctl/tui/catalog_pane.go index e74c05aeb..04cc0e35a 100644 --- a/authbridge/cmd/abctl/tui/catalog_pane.go +++ b/authbridge/cmd/abctl/tui/catalog_pane.go @@ -5,7 +5,7 @@ import ( "github.com/charmbracelet/bubbles/table" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/apiclient" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/apiclient" ) // newCatalogTable builds the registered-plugin catalog table. Same diff --git a/authbridge/cmd/abctl/tui/catalog_pane_test.go b/authbridge/cmd/abctl/tui/catalog_pane_test.go index cfd219d1d..76f7fb235 100644 --- a/authbridge/cmd/abctl/tui/catalog_pane_test.go +++ b/authbridge/cmd/abctl/tui/catalog_pane_test.go @@ -5,7 +5,7 @@ import ( "strings" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/apiclient" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/apiclient" ) func TestRebuildCatalogTable_RendersEntries(t *testing.T) { diff --git a/authbridge/cmd/abctl/tui/deps.go b/authbridge/cmd/abctl/tui/deps.go index 21c97f3b2..2229d6447 100644 --- a/authbridge/cmd/abctl/tui/deps.go +++ b/authbridge/cmd/abctl/tui/deps.go @@ -3,7 +3,7 @@ package tui import ( "fmt" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/apiclient" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/apiclient" ) // depCheck describes whether one declared dependency is satisfied by diff --git a/authbridge/cmd/abctl/tui/deps_test.go b/authbridge/cmd/abctl/tui/deps_test.go index 9e4630176..5cb80d937 100644 --- a/authbridge/cmd/abctl/tui/deps_test.go +++ b/authbridge/cmd/abctl/tui/deps_test.go @@ -3,7 +3,7 @@ package tui import ( "testing" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/apiclient" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/apiclient" ) func TestPluginDepsAllSatisfied_RequiresMet(t *testing.T) { diff --git a/authbridge/cmd/abctl/tui/detail_pane.go b/authbridge/cmd/abctl/tui/detail_pane.go index 557b9bf01..d8adbc2a8 100644 --- a/authbridge/cmd/abctl/tui/detail_pane.go +++ b/authbridge/cmd/abctl/tui/detail_pane.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/charmbracelet/x/ansi" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // showDetail loads the row's event into the detail viewport as colorized @@ -82,7 +82,7 @@ func tunnelHeader(tunnel *pipeline.SessionEvent) string { // // TLS: // version: TLS 1.3 · cipher: TLS_AES_128_GCM_SHA256 -// peer: spiffe://kagenti.local/ns/team1/sa/caller-agent +// peer: spiffe://rossoctl.local/ns/team1/sa/caller-agent // // Empty fields are skipped so the block stays terse on partial data. func tlsHeader(tls *pipeline.EventTLS) string { diff --git a/authbridge/cmd/abctl/tui/detail_pane_test.go b/authbridge/cmd/abctl/tui/detail_pane_test.go index 74d013a5f..a06241aaf 100644 --- a/authbridge/cmd/abctl/tui/detail_pane_test.go +++ b/authbridge/cmd/abctl/tui/detail_pane_test.go @@ -4,7 +4,7 @@ import ( "strings" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // tlsHeader returns "" for plaintext events so callers can prepend @@ -21,13 +21,13 @@ func TestTLSHeader_FullState(t *testing.T) { got := tlsHeader(&pipeline.EventTLS{ Version: "TLS 1.3", CipherSuite: "TLS_AES_128_GCM_SHA256", - PeerSPIFFEID: "spiffe://kagenti.local/ns/team1/sa/caller-agent", + PeerSPIFFEID: "spiffe://rossoctl.local/ns/team1/sa/caller-agent", }) for _, want := range []string{ "TLS:", "version: TLS 1.3", "cipher: TLS_AES_128_GCM_SHA256", - "peer: spiffe://kagenti.local/ns/team1/sa/caller-agent", + "peer: spiffe://rossoctl.local/ns/team1/sa/caller-agent", } { if !strings.Contains(got, want) { t.Errorf("tlsHeader missing %q\ngot:\n%s", want, got) diff --git a/authbridge/cmd/abctl/tui/e2e_test.go b/authbridge/cmd/abctl/tui/e2e_test.go index 754ae6e68..472bd0615 100644 --- a/authbridge/cmd/abctl/tui/e2e_test.go +++ b/authbridge/cmd/abctl/tui/e2e_test.go @@ -8,10 +8,10 @@ import ( tea "github.com/charmbracelet/bubbletea" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/session" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/sessionapi" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/apiclient" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/session" + "github.com/rossoctl/rossocortex/authbridge/authlib/sessionapi" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/apiclient" ) // startStack spins up a real session store + sessionapi.Server on a random diff --git a/authbridge/cmd/abctl/tui/edit_e2e_test.go b/authbridge/cmd/abctl/tui/edit_e2e_test.go index c3a1447f9..33c48cf4e 100644 --- a/authbridge/cmd/abctl/tui/edit_e2e_test.go +++ b/authbridge/cmd/abctl/tui/edit_e2e_test.go @@ -12,7 +12,7 @@ import ( tea "github.com/charmbracelet/bubbletea" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/edit" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/edit" ) const editFixtureCMYAML = `apiVersion: v1 diff --git a/authbridge/cmd/abctl/tui/edit_overlay.go b/authbridge/cmd/abctl/tui/edit_overlay.go index 8665f7fc6..74560651c 100644 --- a/authbridge/cmd/abctl/tui/edit_overlay.go +++ b/authbridge/cmd/abctl/tui/edit_overlay.go @@ -7,7 +7,7 @@ import ( "github.com/charmbracelet/lipgloss" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/edit" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/edit" ) // editPhase tracks where the edit state machine currently sits. diff --git a/authbridge/cmd/abctl/tui/events_pane.go b/authbridge/cmd/abctl/tui/events_pane.go index 574fff9d5..c2ae808ca 100644 --- a/authbridge/cmd/abctl/tui/events_pane.go +++ b/authbridge/cmd/abctl/tui/events_pane.go @@ -10,7 +10,7 @@ import ( "github.com/charmbracelet/bubbles/table" "github.com/charmbracelet/lipgloss" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // newEventsTable builds an empty events table. Uses the shared tableStyles diff --git a/authbridge/cmd/abctl/tui/events_pane_test.go b/authbridge/cmd/abctl/tui/events_pane_test.go index 02855b35a..3b5c07429 100644 --- a/authbridge/cmd/abctl/tui/events_pane_test.go +++ b/authbridge/cmd/abctl/tui/events_pane_test.go @@ -7,7 +7,7 @@ import ( tea "github.com/charmbracelet/bubbletea" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // TestPageActivePane_EventsTable verifies PgDn/PgUp page the events table by a diff --git a/authbridge/cmd/abctl/tui/keys.go b/authbridge/cmd/abctl/tui/keys.go index 8898ef3f3..43433a66f 100644 --- a/authbridge/cmd/abctl/tui/keys.go +++ b/authbridge/cmd/abctl/tui/keys.go @@ -7,8 +7,8 @@ import ( "github.com/charmbracelet/bubbles/table" tea "github.com/charmbracelet/bubbletea" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/apiclient" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/edit" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/apiclient" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/edit" ) // catalogPlugins extracts the plugin slice from a (possibly nil) diff --git a/authbridge/cmd/abctl/tui/namespaces_pane.go b/authbridge/cmd/abctl/tui/namespaces_pane.go index 7a99ffc53..011f60a32 100644 --- a/authbridge/cmd/abctl/tui/namespaces_pane.go +++ b/authbridge/cmd/abctl/tui/namespaces_pane.go @@ -10,9 +10,9 @@ import ( "github.com/charmbracelet/bubbles/viewport" tea "github.com/charmbracelet/bubbletea" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/cluster" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/edit" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/cluster" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/edit" ) // newNamespacesTable builds an empty namespaces picker table. diff --git a/authbridge/cmd/abctl/tui/picker_test.go b/authbridge/cmd/abctl/tui/picker_test.go index 59197b951..66d1d575b 100644 --- a/authbridge/cmd/abctl/tui/picker_test.go +++ b/authbridge/cmd/abctl/tui/picker_test.go @@ -9,8 +9,8 @@ import ( tea "github.com/charmbracelet/bubbletea" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/apiclient" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/cluster" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/apiclient" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/cluster" ) // fakeLister returns a fixed []AgentNamespace and counts ListAgents calls. diff --git a/authbridge/cmd/abctl/tui/pipeline_pane.go b/authbridge/cmd/abctl/tui/pipeline_pane.go index 39d06b554..46b32fbec 100644 --- a/authbridge/cmd/abctl/tui/pipeline_pane.go +++ b/authbridge/cmd/abctl/tui/pipeline_pane.go @@ -5,7 +5,7 @@ import ( "github.com/charmbracelet/bubbles/table" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/apiclient" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/apiclient" ) // newPipelineTable builds the plugins table shown on the Pipeline top-level diff --git a/authbridge/cmd/abctl/tui/pipeline_pane_test.go b/authbridge/cmd/abctl/tui/pipeline_pane_test.go index d94c07862..4f49d2f24 100644 --- a/authbridge/cmd/abctl/tui/pipeline_pane_test.go +++ b/authbridge/cmd/abctl/tui/pipeline_pane_test.go @@ -3,7 +3,7 @@ package tui import ( "testing" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/apiclient" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/apiclient" ) // TestRebuildPipelineTable_AllRowsMatchColumnCount is a regression guard: diff --git a/authbridge/cmd/abctl/tui/plugin_detail_pane.go b/authbridge/cmd/abctl/tui/plugin_detail_pane.go index a786b0c1a..a5cc9b102 100644 --- a/authbridge/cmd/abctl/tui/plugin_detail_pane.go +++ b/authbridge/cmd/abctl/tui/plugin_detail_pane.go @@ -4,7 +4,7 @@ import ( "fmt" "strings" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/apiclient" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/apiclient" ) // showPluginDetail loads the focused plugin into the detail viewport. diff --git a/authbridge/cmd/abctl/tui/plugin_detail_pane_test.go b/authbridge/cmd/abctl/tui/plugin_detail_pane_test.go index 3f2890c21..dd5ae96f5 100644 --- a/authbridge/cmd/abctl/tui/plugin_detail_pane_test.go +++ b/authbridge/cmd/abctl/tui/plugin_detail_pane_test.go @@ -6,7 +6,7 @@ import ( "strings" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/apiclient" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/apiclient" ) func TestShowPluginDetailRendersConfig(t *testing.T) { diff --git a/authbridge/cmd/abctl/tui/pods_pane.go b/authbridge/cmd/abctl/tui/pods_pane.go index 1b2cd9423..6511ea11d 100644 --- a/authbridge/cmd/abctl/tui/pods_pane.go +++ b/authbridge/cmd/abctl/tui/pods_pane.go @@ -6,7 +6,7 @@ import ( "github.com/charmbracelet/bubbles/table" tea "github.com/charmbracelet/bubbletea" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/cluster" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/cluster" ) // newPodsTable builds an empty pods picker table. diff --git a/authbridge/cmd/abctl/tui/sessions_pane.go b/authbridge/cmd/abctl/tui/sessions_pane.go index 75b4f713a..c49279767 100644 --- a/authbridge/cmd/abctl/tui/sessions_pane.go +++ b/authbridge/cmd/abctl/tui/sessions_pane.go @@ -7,7 +7,7 @@ import ( "github.com/charmbracelet/bubbles/table" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // newSessionsTable builds an empty sessions table. diff --git a/authbridge/cmd/authbridge-cpex/go.mod b/authbridge/cmd/authbridge-cpex/go.mod index 6805a8055..073d9c484 100644 --- a/authbridge/cmd/authbridge-cpex/go.mod +++ b/authbridge/cmd/authbridge-cpex/go.mod @@ -1,8 +1,8 @@ -module github.com/kagenti/kagenti-extensions/authbridge/cmd/authbridge-cpex +module github.com/rossoctl/rossocortex/authbridge/cmd/authbridge-cpex go 1.26.4 -require github.com/kagenti/kagenti-extensions/authbridge/authlib v0.0.0-00010101000000-000000000000 +require github.com/rossoctl/rossocortex/authbridge/authlib v0.0.0-00010101000000-000000000000 require ( github.com/Microsoft/go-winio v0.6.2 // indirect @@ -38,4 +38,4 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect ) -replace github.com/kagenti/kagenti-extensions/authbridge/authlib => ../../authlib +replace github.com/rossoctl/rossocortex/authbridge/authlib => ../../authlib diff --git a/authbridge/cmd/authbridge-cpex/main.go b/authbridge/cmd/authbridge-cpex/main.go index fc209a1e8..aedd51771 100644 --- a/authbridge/cmd/authbridge-cpex/main.go +++ b/authbridge/cmd/authbridge-cpex/main.go @@ -1,7 +1,7 @@ //go:build cpex // Package main is the CPEX-enabled authbridge binary: identical to -// authbridge-proxy (HTTP forward + reverse proxies, full kagenti +// authbridge-proxy (HTTP forward + reverse proxies, full rossoctl // plugin set) plus the `cpex` plugin which routes hooks through the // CPEX (Context Plugin Execution) framework — including the APL DSL // and any pre-built CPEX policy plugins (Cedar, PII scanner, audit @@ -31,34 +31,34 @@ import ( "syscall" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/auth" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/config" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/observe" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/reloader" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/session" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/sessionapi" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/shared" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/spiffe" - authtls "github.com/kagenti/kagenti-extensions/authbridge/authlib/tls" - - "github.com/kagenti/kagenti-extensions/authbridge/authlib/listener/forwardproxy" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/listener/reverseproxy" + "github.com/rossoctl/rossocortex/authbridge/authlib/auth" + "github.com/rossoctl/rossocortex/authbridge/authlib/config" + "github.com/rossoctl/rossocortex/authbridge/authlib/observe" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins" + "github.com/rossoctl/rossocortex/authbridge/authlib/reloader" + "github.com/rossoctl/rossocortex/authbridge/authlib/session" + "github.com/rossoctl/rossocortex/authbridge/authlib/sessionapi" + "github.com/rossoctl/rossocortex/authbridge/authlib/shared" + "github.com/rossoctl/rossocortex/authbridge/authlib/spiffe" + authtls "github.com/rossoctl/rossocortex/authbridge/authlib/tls" + + "github.com/rossoctl/rossocortex/authbridge/authlib/listener/forwardproxy" + "github.com/rossoctl/rossocortex/authbridge/authlib/listener/reverseproxy" // Plugins — same set as authbridge-proxy, plus the cpex plugin // which lives behind //go:build cpex. The cpex import only fires // in this binary's build; pure-Go binaries (authbridge-proxy, // authbridge-envoy, authbridge-lite) don't import it. - _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/a2aparser" - _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/cpex" - _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/ibac" - _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/inferenceparser" - _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/jwtvalidation" - _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/mcpparser" - _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/sparc" - _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/tokenbroker" - _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/tokenexchange" + _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/a2aparser" + _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/cpex" + _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/ibac" + _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/inferenceparser" + _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/jwtvalidation" + _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/mcpparser" + _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/sparc" + _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/tokenbroker" + _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/tokenexchange" ) var logLevel = new(slog.LevelVar) diff --git a/authbridge/cmd/authbridge-envoy/Dockerfile b/authbridge/cmd/authbridge-envoy/Dockerfile index 40c343b89..bfacbbfe5 100644 --- a/authbridge/cmd/authbridge-envoy/Dockerfile +++ b/authbridge/cmd/authbridge-envoy/Dockerfile @@ -10,7 +10,7 @@ # `-ldflags="-s -w"` drops the symbol table and DWARF debug info to # shave ~30% off the binary. Go's runtime keeps `pclntab` separately, # so panic stack traces still show function names. -# authlib embeds github.com/kagenti/context-guru (a published module, fetched via +# authlib embeds github.com/rossoctl/context-guru (a published module, fetched via # GOPROXY). It is pure-Go (skeleton cgo is behind the cg_skeleton tag), so # CGO_ENABLED=0 stays correct. FROM golang:1.26-alpine@sha256:0178a641fbb4858c5f1b48e34bdaabe0350a330a1b1149aabd498d0699ff5fb2 AS builder diff --git a/authbridge/cmd/authbridge-envoy/go.mod b/authbridge/cmd/authbridge-envoy/go.mod index 5d8cf321f..5850ce1c3 100644 --- a/authbridge/cmd/authbridge-envoy/go.mod +++ b/authbridge/cmd/authbridge-envoy/go.mod @@ -1,12 +1,12 @@ -module github.com/kagenti/kagenti-extensions/authbridge/cmd/authbridge-envoy +module github.com/rossoctl/rossocortex/authbridge/cmd/authbridge-envoy go 1.26.4 -replace github.com/kagenti/kagenti-extensions/authbridge/authlib => ../../authlib +replace github.com/rossoctl/rossocortex/authbridge/authlib => ../../authlib require ( github.com/envoyproxy/go-control-plane/envoy v1.37.0 - github.com/kagenti/kagenti-extensions/authbridge/authlib v0.0.0-00010101000000-000000000000 + github.com/rossoctl/rossocortex/authbridge/authlib v0.0.0-00010101000000-000000000000 google.golang.org/grpc v1.82.0 ) @@ -54,7 +54,7 @@ require ( github.com/huandu/go-sqlbuilder v1.41.0 // indirect github.com/huandu/xstrings v1.4.0 // indirect github.com/invopop/jsonschema v0.13.0 // indirect - github.com/kagenti/context-guru v0.0.0-20260713113308-b624f2c3d8c2 // indirect + github.com/rossoctl/context-guru v0.0.0-20260713113308-b624f2c3d8c2 // indirect github.com/klauspost/compress v1.18.6 // indirect github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/lestrrat-go/blackmagic v1.0.4 // indirect diff --git a/authbridge/cmd/authbridge-envoy/go.sum b/authbridge/cmd/authbridge-envoy/go.sum index 926aaafeb..1b0143674 100644 --- a/authbridge/cmd/authbridge-envoy/go.sum +++ b/authbridge/cmd/authbridge-envoy/go.sum @@ -122,8 +122,8 @@ github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= -github.com/kagenti/context-guru v0.0.0-20260713113308-b624f2c3d8c2 h1:nyu0kAd/+NlRM95IxEiRws2QyRtyyYRy8u8wjnwxn4o= -github.com/kagenti/context-guru v0.0.0-20260713113308-b624f2c3d8c2/go.mod h1:arqPc8H+3s+XjplrD0ytgv1Zum241jvuGu3139DX6p8= +github.com/rossoctl/context-guru v0.0.0-20260713113308-b624f2c3d8c2 h1:nyu0kAd/+NlRM95IxEiRws2QyRtyyYRy8u8wjnwxn4o= +github.com/rossoctl/context-guru v0.0.0-20260713113308-b624f2c3d8c2/go.mod h1:arqPc8H+3s+XjplrD0ytgv1Zum241jvuGu3139DX6p8= github.com/klauspost/compress v1.18.6 h1:2jupLlAwFm95+YDR+NwD2MEfFO9d4z4Prjl1XXDjuao= github.com/klauspost/compress v1.18.6/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= diff --git a/authbridge/cmd/authbridge-envoy/main.go b/authbridge/cmd/authbridge-envoy/main.go index 41d99b284..5a29b875b 100644 --- a/authbridge/cmd/authbridge-envoy/main.go +++ b/authbridge/cmd/authbridge-envoy/main.go @@ -31,32 +31,32 @@ import ( healthpb "google.golang.org/grpc/health/grpc_health_v1" "google.golang.org/grpc/reflection" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/auth" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/config" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/observe" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/reloader" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/session" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/sessionapi" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/shared" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/spiffe" + "github.com/rossoctl/rossocortex/authbridge/authlib/auth" + "github.com/rossoctl/rossocortex/authbridge/authlib/config" + "github.com/rossoctl/rossocortex/authbridge/authlib/observe" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins" + "github.com/rossoctl/rossocortex/authbridge/authlib/reloader" + "github.com/rossoctl/rossocortex/authbridge/authlib/session" + "github.com/rossoctl/rossocortex/authbridge/authlib/sessionapi" + "github.com/rossoctl/rossocortex/authbridge/authlib/shared" + "github.com/rossoctl/rossocortex/authbridge/authlib/spiffe" // Only the ext_proc listener is compiled in (no ext_authz, no // HTTP proxies). - "github.com/kagenti/kagenti-extensions/authbridge/authlib/listener/extproc" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/listener/skiphost" + "github.com/rossoctl/rossocortex/authbridge/authlib/listener/extproc" + "github.com/rossoctl/rossocortex/authbridge/authlib/listener/skiphost" // Plugins. Auth gates first, then the protocol parsers that // supply session-event context for abctl. - _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/a2aparser" - _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/inferenceparser" - _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/jwtvalidation" - _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/mcpparser" - _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/opa" - _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/sparc" - _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/tokenbroker" - _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/tokenexchange" + _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/a2aparser" + _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/inferenceparser" + _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/jwtvalidation" + _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/mcpparser" + _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/opa" + _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/sparc" + _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/tokenbroker" + _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/tokenexchange" ) var logLevel = new(slog.LevelVar) diff --git a/authbridge/cmd/authbridge-envoy/plugins_contextguru.go b/authbridge/cmd/authbridge-envoy/plugins_contextguru.go index cc01dcf30..a269b7910 100644 --- a/authbridge/cmd/authbridge-envoy/plugins_contextguru.go +++ b/authbridge/cmd/authbridge-envoy/plugins_contextguru.go @@ -7,4 +7,4 @@ // linked only when built with -tags include_plugin_contextguru. package main -import _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/contextguru" +import _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/contextguru" diff --git a/authbridge/cmd/authbridge-envoy/plugins_ibac.go b/authbridge/cmd/authbridge-envoy/plugins_ibac.go index 692d9a5e0..d7e23f655 100644 --- a/authbridge/cmd/authbridge-envoy/plugins_ibac.go +++ b/authbridge/cmd/authbridge-envoy/plugins_ibac.go @@ -2,4 +2,4 @@ package main -import _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/ibac" +import _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/ibac" diff --git a/authbridge/cmd/authbridge-proxy/Dockerfile b/authbridge/cmd/authbridge-proxy/Dockerfile index 3f5fd5ab9..f1da5eb46 100644 --- a/authbridge/cmd/authbridge-proxy/Dockerfile +++ b/authbridge/cmd/authbridge-proxy/Dockerfile @@ -13,7 +13,7 @@ # # Build context: ./authbridge (needs access to authlib/ and cmd/authbridge-proxy/) # -# authlib embeds github.com/kagenti/context-guru (a published module, fetched via +# authlib embeds github.com/rossoctl/context-guru (a published module, fetched via # GOPROXY like any other dependency). It builds pure-Go — skeleton's cgo is behind # the cg_skeleton build tag — so CGO_ENABLED=0 below stays correct. diff --git a/authbridge/cmd/authbridge-proxy/go.mod b/authbridge/cmd/authbridge-proxy/go.mod index 1e4bc8be6..d49f01477 100644 --- a/authbridge/cmd/authbridge-proxy/go.mod +++ b/authbridge/cmd/authbridge-proxy/go.mod @@ -1,8 +1,8 @@ -module github.com/kagenti/kagenti-extensions/authbridge/cmd/authbridge-proxy +module github.com/rossoctl/rossocortex/authbridge/cmd/authbridge-proxy go 1.26.4 -require github.com/kagenti/kagenti-extensions/authbridge/authlib v0.0.0-00010101000000-000000000000 +require github.com/rossoctl/rossocortex/authbridge/authlib v0.0.0-00010101000000-000000000000 require ( github.com/Microsoft/go-winio v0.6.2 // indirect @@ -46,7 +46,7 @@ require ( github.com/huandu/go-sqlbuilder v1.41.0 // indirect github.com/huandu/xstrings v1.4.0 // indirect github.com/invopop/jsonschema v0.13.0 // indirect - github.com/kagenti/context-guru v0.0.0-20260713113308-b624f2c3d8c2 // indirect + github.com/rossoctl/context-guru v0.0.0-20260713113308-b624f2c3d8c2 // indirect github.com/klauspost/compress v1.18.6 // indirect github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/lestrrat-go/blackmagic v1.0.4 // indirect @@ -118,4 +118,4 @@ require ( sigs.k8s.io/yaml v1.6.0 // indirect ) -replace github.com/kagenti/kagenti-extensions/authbridge/authlib => ../../authlib +replace github.com/rossoctl/rossocortex/authbridge/authlib => ../../authlib diff --git a/authbridge/cmd/authbridge-proxy/go.sum b/authbridge/cmd/authbridge-proxy/go.sum index a189d8c86..c389e18e8 100644 --- a/authbridge/cmd/authbridge-proxy/go.sum +++ b/authbridge/cmd/authbridge-proxy/go.sum @@ -116,8 +116,8 @@ github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= -github.com/kagenti/context-guru v0.0.0-20260713113308-b624f2c3d8c2 h1:nyu0kAd/+NlRM95IxEiRws2QyRtyyYRy8u8wjnwxn4o= -github.com/kagenti/context-guru v0.0.0-20260713113308-b624f2c3d8c2/go.mod h1:arqPc8H+3s+XjplrD0ytgv1Zum241jvuGu3139DX6p8= +github.com/rossoctl/context-guru v0.0.0-20260713113308-b624f2c3d8c2 h1:nyu0kAd/+NlRM95IxEiRws2QyRtyyYRy8u8wjnwxn4o= +github.com/rossoctl/context-guru v0.0.0-20260713113308-b624f2c3d8c2/go.mod h1:arqPc8H+3s+XjplrD0ytgv1Zum241jvuGu3139DX6p8= github.com/klauspost/compress v1.18.6 h1:2jupLlAwFm95+YDR+NwD2MEfFO9d4z4Prjl1XXDjuao= github.com/klauspost/compress v1.18.6/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= diff --git a/authbridge/cmd/authbridge-proxy/main.go b/authbridge/cmd/authbridge-proxy/main.go index 0ad6f76ca..504c89e7e 100644 --- a/authbridge/cmd/authbridge-proxy/main.go +++ b/authbridge/cmd/authbridge-proxy/main.go @@ -30,25 +30,25 @@ import ( "syscall" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/auth" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/config" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/observe" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/reloader" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/session" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/sessionapi" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/shared" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/spiffe" - authtls "github.com/kagenti/kagenti-extensions/authbridge/authlib/tls" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/tlsbridge" + "github.com/rossoctl/rossocortex/authbridge/authlib/auth" + "github.com/rossoctl/rossocortex/authbridge/authlib/config" + "github.com/rossoctl/rossocortex/authbridge/authlib/observe" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins" + "github.com/rossoctl/rossocortex/authbridge/authlib/reloader" + "github.com/rossoctl/rossocortex/authbridge/authlib/session" + "github.com/rossoctl/rossocortex/authbridge/authlib/sessionapi" + "github.com/rossoctl/rossocortex/authbridge/authlib/shared" + "github.com/rossoctl/rossocortex/authbridge/authlib/spiffe" + authtls "github.com/rossoctl/rossocortex/authbridge/authlib/tls" + "github.com/rossoctl/rossocortex/authbridge/authlib/tlsbridge" // Only HTTP listeners are compiled in: no extproc/extauthz // (no gRPC, no envoy types). - "github.com/kagenti/kagenti-extensions/authbridge/authlib/listener/forwardproxy" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/listener/reverseproxy" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/listener/skiphost" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/listener/transparentproxy" + "github.com/rossoctl/rossocortex/authbridge/authlib/listener/forwardproxy" + "github.com/rossoctl/rossocortex/authbridge/authlib/listener/reverseproxy" + "github.com/rossoctl/rossocortex/authbridge/authlib/listener/skiphost" + "github.com/rossoctl/rossocortex/authbridge/authlib/listener/transparentproxy" // Plugins are wired via per-plugin plugins_.go files, each gated // by `//go:build !exclude_plugin_`. main.go imports no plugin // package directly, so every plugin can be dropped at build time. The diff --git a/authbridge/cmd/authbridge-proxy/main_test.go b/authbridge/cmd/authbridge-proxy/main_test.go index 54ec737d0..32287a3b3 100644 --- a/authbridge/cmd/authbridge-proxy/main_test.go +++ b/authbridge/cmd/authbridge-proxy/main_test.go @@ -4,9 +4,9 @@ import ( "encoding/json" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/config" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/tokenexchange" + "github.com/rossoctl/rossocortex/authbridge/authlib/config" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/tokenexchange" ) func identityConfig(idType string) json.RawMessage { diff --git a/authbridge/cmd/authbridge-proxy/plugins_a2aparser.go b/authbridge/cmd/authbridge-proxy/plugins_a2aparser.go index 99dbeb6ef..1ef103470 100644 --- a/authbridge/cmd/authbridge-proxy/plugins_a2aparser.go +++ b/authbridge/cmd/authbridge-proxy/plugins_a2aparser.go @@ -2,4 +2,4 @@ package main -import _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/a2aparser" +import _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/a2aparser" diff --git a/authbridge/cmd/authbridge-proxy/plugins_contextguru.go b/authbridge/cmd/authbridge-proxy/plugins_contextguru.go index cc01dcf30..a269b7910 100644 --- a/authbridge/cmd/authbridge-proxy/plugins_contextguru.go +++ b/authbridge/cmd/authbridge-proxy/plugins_contextguru.go @@ -7,4 +7,4 @@ // linked only when built with -tags include_plugin_contextguru. package main -import _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/contextguru" +import _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/contextguru" diff --git a/authbridge/cmd/authbridge-proxy/plugins_ibac.go b/authbridge/cmd/authbridge-proxy/plugins_ibac.go index 692d9a5e0..d7e23f655 100644 --- a/authbridge/cmd/authbridge-proxy/plugins_ibac.go +++ b/authbridge/cmd/authbridge-proxy/plugins_ibac.go @@ -2,4 +2,4 @@ package main -import _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/ibac" +import _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/ibac" diff --git a/authbridge/cmd/authbridge-proxy/plugins_inferenceparser.go b/authbridge/cmd/authbridge-proxy/plugins_inferenceparser.go index cfb1bde6a..9a31ae14a 100644 --- a/authbridge/cmd/authbridge-proxy/plugins_inferenceparser.go +++ b/authbridge/cmd/authbridge-proxy/plugins_inferenceparser.go @@ -2,4 +2,4 @@ package main -import _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/inferenceparser" +import _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/inferenceparser" diff --git a/authbridge/cmd/authbridge-proxy/plugins_jwtvalidation.go b/authbridge/cmd/authbridge-proxy/plugins_jwtvalidation.go index a67edd23f..7d5a0459a 100644 --- a/authbridge/cmd/authbridge-proxy/plugins_jwtvalidation.go +++ b/authbridge/cmd/authbridge-proxy/plugins_jwtvalidation.go @@ -2,4 +2,4 @@ package main -import _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/jwtvalidation" +import _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/jwtvalidation" diff --git a/authbridge/cmd/authbridge-proxy/plugins_litellm_budgettrack.go b/authbridge/cmd/authbridge-proxy/plugins_litellm_budgettrack.go index f3c5aa174..c7d904f08 100644 --- a/authbridge/cmd/authbridge-proxy/plugins_litellm_budgettrack.go +++ b/authbridge/cmd/authbridge-proxy/plugins_litellm_budgettrack.go @@ -2,4 +2,4 @@ package main -import _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/litellm_budgettrack" +import _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/litellm_budgettrack" diff --git a/authbridge/cmd/authbridge-proxy/plugins_mcpparser.go b/authbridge/cmd/authbridge-proxy/plugins_mcpparser.go index 5e8db1c86..289f169a9 100644 --- a/authbridge/cmd/authbridge-proxy/plugins_mcpparser.go +++ b/authbridge/cmd/authbridge-proxy/plugins_mcpparser.go @@ -2,4 +2,4 @@ package main -import _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/mcpparser" +import _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/mcpparser" diff --git a/authbridge/cmd/authbridge-proxy/plugins_opa.go b/authbridge/cmd/authbridge-proxy/plugins_opa.go index 040c2d2c7..b77acd285 100644 --- a/authbridge/cmd/authbridge-proxy/plugins_opa.go +++ b/authbridge/cmd/authbridge-proxy/plugins_opa.go @@ -2,4 +2,4 @@ package main -import _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/opa" +import _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/opa" diff --git a/authbridge/cmd/authbridge-proxy/plugins_sparc.go b/authbridge/cmd/authbridge-proxy/plugins_sparc.go index 4f6108bc1..f04338b0c 100644 --- a/authbridge/cmd/authbridge-proxy/plugins_sparc.go +++ b/authbridge/cmd/authbridge-proxy/plugins_sparc.go @@ -2,4 +2,4 @@ package main -import _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/sparc" +import _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/sparc" diff --git a/authbridge/cmd/authbridge-proxy/plugins_staticinject.go b/authbridge/cmd/authbridge-proxy/plugins_staticinject.go index b1efc8df9..9eb45c45c 100644 --- a/authbridge/cmd/authbridge-proxy/plugins_staticinject.go +++ b/authbridge/cmd/authbridge-proxy/plugins_staticinject.go @@ -2,4 +2,4 @@ package main -import _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/staticinject" +import _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/staticinject" diff --git a/authbridge/cmd/authbridge-proxy/plugins_tokenbroker.go b/authbridge/cmd/authbridge-proxy/plugins_tokenbroker.go index acccd402f..d411a73ce 100644 --- a/authbridge/cmd/authbridge-proxy/plugins_tokenbroker.go +++ b/authbridge/cmd/authbridge-proxy/plugins_tokenbroker.go @@ -2,4 +2,4 @@ package main -import _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/tokenbroker" +import _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/tokenbroker" diff --git a/authbridge/cmd/authbridge-proxy/plugins_tokenexchange.go b/authbridge/cmd/authbridge-proxy/plugins_tokenexchange.go index 653aa6ab6..0d67035c1 100644 --- a/authbridge/cmd/authbridge-proxy/plugins_tokenexchange.go +++ b/authbridge/cmd/authbridge-proxy/plugins_tokenexchange.go @@ -2,4 +2,4 @@ package main -import _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/tokenexchange" +import _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/tokenexchange" diff --git a/authbridge/demos/README.md b/authbridge/demos/README.md index 90b31cb6d..149f63e82 100644 --- a/authbridge/demos/README.md +++ b/authbridge/demos/README.md @@ -5,7 +5,7 @@ authentication for Kubernetes agent workloads. Each demo progressively introduce more AuthBridge capabilities. > **Note:** These demos use the operator-injected combined sidecar (after -> kagenti-extensions#411 — `authbridge` for proxy-sidecar, `authbridge-envoy` +> rossocortex#411 — `authbridge` for proxy-sidecar, `authbridge-envoy` > for envoy-sidecar, and `authbridge-lite`, the proxy image built auth-only > via `exclude_plugin_*` tags). The previous `authbridge-unified` image and the per-component > sidecars (`client-registration`, standalone `spiffe-helper`) have been @@ -21,7 +21,7 @@ more AuthBridge capabilities. | **[Token-Exchange Routes](token-exchange-routes/README.md)** | Reference | How to write `authproxy-routes` for single- and multi-target token exchange | Configuration only | | **[MCP Parser Plugin](mcp-parser/README.md)** | Reference | Enable the `mcp-parser` plugin to surface tool calls / resource reads in session events | Configuration only | | **[abctl Walkthrough](weather-agent/demo-with-abctl.md)** | Reference | Watch the AuthBridge plugin pipeline live with the `abctl` TUI | Tooling only | -| **[IBAC](ibac/README.md)** | Intermediate | Intent-Based Access Control: LLM judge denies outbound HTTP that doesn't align with the user's recorded intent. Reproduces the email-poison / prompt-injection attack from `huang195/ibac`; chat with the agent through the kagenti UI and see the exfiltration blocked, then `make show-result` for a pipeline-level forensic | UI + kubectl | +| **[IBAC](ibac/README.md)** | Intermediate | Intent-Based Access Control: LLM judge denies outbound HTTP that doesn't align with the user's recorded intent. Reproduces the email-poison / prompt-injection attack from `huang195/ibac`; chat with the agent through the rossoctl UI and see the exfiltration blocked, then `make show-result` for a pipeline-level forensic | UI + kubectl | | **[SPARC (finance)](finance-sparc/README.md)** | Intermediate | SPARC pre-tool reflection: the `sparc` plugin blocks a hallucinated/ungrounded tool argument (an invented transaction id) before it executes and transparently asks the user to clarify, then approves the corrected call. Complements IBAC — SPARC verifies argument grounding, IBAC verifies intent alignment | UI + kubectl | | **[CPEX Bridge (HR)](hr-cpex/README.md)** | Advanced | CPEX/APL declarative policy: one route chains a coarse APL predicate, an embedded Cedar PDP, RFC 8693 token exchange with a post-check, PII redaction and audit plugins. Same request, different data per caller (Bob sees an SSN, Eve gets it redacted). Self-contained: its own kind cluster + namespace, deployed via `make` rather than operator injection | [kubectl (make)](hr-cpex/README.md#quick-start) | @@ -30,7 +30,7 @@ more AuthBridge capabilities. **New to AuthBridge?** Start with the demos in this order: 1. **[Weather Agent](weather-agent/demo-ui.md)** — Fastest way to see AuthBridge - in action. Deploys via the Kagenti UI with inbound JWT validation protecting + in action. Deploys via the Rossoctl UI with inbound JWT validation protecting the agent. No token exchange configuration needed; outbound traffic uses the default passthrough policy. @@ -48,7 +48,7 @@ more AuthBridge capabilities. ## What Each Demo Covers ### Weather Agent (Getting Started) -- Deploy agent + tool via **Kagenti UI** +- Deploy agent + tool via **Rossoctl UI** - AuthBridge inbound JWT validation (signature, issuer, audience) - Automatic SPIFFE identity registration with Keycloak - Default outbound passthrough — agents work out-of-the-box with any tool or LLM @@ -63,7 +63,7 @@ more AuthBridge capabilities. exchange + MCP `initialize` without requiring a working LLM) ### GitHub Issue Agent (Full AuthBridge Flow) -- Deploy agent + tool via **Kagenti UI** or **kubectl** +- Deploy agent + tool via **Rossoctl UI** or **kubectl** - Keycloak configuration for token exchange (realm, clients, scopes) - Inbound JWT validation protecting the agent - Outbound OAuth 2.0 token exchange (RFC 8693) — agent-scoped token exchanged @@ -112,13 +112,13 @@ more AuthBridge capabilities. ## Prerequisites All demos require: -- A Kubernetes cluster with the Kagenti platform installed - ([Installation Guide](https://github.com/kagenti/kagenti/blob/main/docs/install.md)) +- A Kubernetes cluster with the Rossoctl platform installed + ([Installation Guide](https://github.com/rossoctl/rossoctl/blob/main/docs/install.md)) - Keycloak deployed in the `keycloak` namespace - SPIRE deployed (for demos using SPIFFE identity) UI-based demos additionally require: -- The Kagenti UI running at `http://kagenti-ui.localtest.me:8080` +- The Rossoctl UI running at `http://rossoctl-ui.localtest.me:8080` ## Common Setup: Keycloak Port-Forward @@ -147,4 +147,4 @@ pip install -r requirements.txt - [AuthBridge Overview](../README.md) — Architecture and design - [AuthBridge Binary](../cmd/authbridge/README.md) — Unified authbridge binary supporting ext_proc, ext_authz, and proxy modes -- [Kagenti Operator](https://github.com/kagenti/kagenti-operator) — Admission webhook for sidecar injection (migrated from this repo) +- [Rossoctl Operator](https://github.com/rossoctl/operator) — Admission webhook for sidecar injection (migrated from this repo) diff --git a/authbridge/demos/context-guru/README.md b/authbridge/demos/context-guru/README.md index ce8c2e5e2..66b2b0b40 100644 --- a/authbridge/demos/context-guru/README.md +++ b/authbridge/demos/context-guru/README.md @@ -1,6 +1,6 @@ # context-guru demo — context engineering that keeps an agent under its window -This demo runs the **context-guru** AuthBridge plugin in front of a real Kagenti +This demo runs the **context-guru** AuthBridge plugin in front of a real Rossoctl agent and shows the plugin doing real context engineering: it compacts the agent's growing tool-output context before it reaches the LLM, so a task whose raw context **exceeds the model's window** still fits — and the agent gets the @@ -101,7 +101,7 @@ export CG_MODEL_BASE=https://api.openai.com # any OpenAI-wire `run.sh setup` builds the `authbridge-proxy` image **with the context-guru plugin** (`-tags include_plugin_contextguru` — see *Build integration* below), loads it + the -enhanced `finance-mcp` into the `kagenti` kind cluster, creates a 12,288-token-window +enhanced `finance-mcp` into the `rossoctl` kind cluster, creates a 12,288-token-window Ollama model (`llama3.2-ctx12k`) so the raw request truncates, and deploys the agent + sidecar. `run.sh drive ` flips `on_error`, restarts, drives the audit, and prints the agent's answer + the byte/token gain from the sidecar session API (`:9094`). @@ -135,7 +135,7 @@ cd authbridge && podman build -f cmd/authbridge-proxy/Dockerfile \ | `config.engine.components.extract.marker_mode` | `full` (reversible, stashes) \| `summary` (breadcrumb) \| `off` (silent) | | `config.engine.components.*.trigger` / thresholds | per-component gates (min tokens, head/tail lines) | -`k8s/agent.yaml` deploys the agent + sidecar with **no `kagenti.io/inject` label**, +`k8s/agent.yaml` deploys the agent + sidecar with **no `rossoctl.io/inject` label**, so the demo owns both containers and the config (the operator webhook doesn't inject a second sidecar). The extract-code key lives in the `cg-model-key` Secret. diff --git a/authbridge/demos/context-guru/k8s/agent.yaml b/authbridge/demos/context-guru/k8s/agent.yaml index 554cbf460..9373fd474 100644 --- a/authbridge/demos/context-guru/k8s/agent.yaml +++ b/authbridge/demos/context-guru/k8s/agent.yaml @@ -1,5 +1,5 @@ # A finance agent + a context-guru-enabled AuthBridge sidecar, deployed WITHOUT -# the operator's mutating webhook (no kagenti.io/inject label) so the demo owns +# the operator's mutating webhook (no rossoctl.io/inject label) so the demo owns # both containers and the /etc/authbridge/config.yaml. # # The agent's outbound LLM traffic (OpenAI /v1/chat/completions to Ollama) is @@ -18,8 +18,8 @@ spec: metadata: labels: app.kubernetes.io/name: cg-finance-agent - protocol.kagenti.io/a2a: "" - # deliberately NO kagenti.io/inject -> the operator webhook does not inject a sidecar + protocol.rossoctl.io/a2a: "" + # deliberately NO rossoctl.io/inject -> the operator webhook does not inject a sidecar spec: containers: - name: agent diff --git a/authbridge/demos/context-guru/run.sh b/authbridge/demos/context-guru/run.sh index d5909c2b2..741947721 100755 --- a/authbridge/demos/context-guru/run.sh +++ b/authbridge/demos/context-guru/run.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# End-to-end context-guru demo on a real Kagenti (kind) cluster. +# End-to-end context-guru demo on a real Rossoctl (kind) cluster. # # ./run.sh setup # build+load images, create the 12k-window model, deploy agent+sidecar # ./run.sh drive # mode = enforce | observe | off ; drives the audit, prints answer + gain @@ -12,7 +12,7 @@ # the anomaly, with context-guru it is compacted (~10K tokens), fits, and the # agent answers correctly. # -# Prereqs: a running Kagenti kind cluster ("kagenti") with the finance-sparc +# Prereqs: a running Rossoctl kind cluster ("rossoctl") with the finance-sparc # finance-agent:latest image, and a host Ollama (llama3.2:3b) reachable at # OLLAMA_URL. CG_MODEL_KEY must be a key for an OpenAI-compatible extract-code model. set -euo pipefail @@ -27,7 +27,7 @@ CTX_MODEL="llama3.2-ctx12k" setup() { : "${CG_MODEL_KEY:?set CG_MODEL_KEY to the extract-code model API key}" : "${CG_MODEL_BASE:?set CG_MODEL_BASE to an OpenAI-compatible endpoint for the extract-code model, e.g. https://api.openai.com}" - local arch; arch=$(docker exec kagenti-control-plane uname -m | sed 's/aarch64/arm64/;s/x86_64/amd64/') + local arch; arch=$(docker exec rossoctl-control-plane uname -m | sed 's/aarch64/arm64/;s/x86_64/amd64/') echo "==> build authbridge-proxy WITH the context-guru plugin ($arch, pure-Go, -tags include_plugin_contextguru) + image" ( cd "$AB" && GOTOOLCHAIN=auto GOOS=linux GOARCH="$arch" CGO_ENABLED=0 \ @@ -40,11 +40,11 @@ COPY authbridge-proxy /usr/local/bin/authbridge-proxy ENTRYPOINT ["/usr/local/bin/authbridge-proxy"] DOCKER docker build -q -t authbridge-cg:latest "$d" >/dev/null - kind load docker-image authbridge-cg:latest --name kagenti + kind load docker-image authbridge-cg:latest --name rossoctl echo "==> build+load finance-mcp (large-output tools: get_transaction_audit, get_customer_ledger)" ( cd "$FS" && docker build -q -f finance-mcp/Dockerfile -t finance-mcp:latest . >/dev/null ) - kind load docker-image finance-mcp:latest --name kagenti + kind load docker-image finance-mcp:latest --name rossoctl kubectl -n "$NS" rollout restart deploy/finance-mcp >/dev/null kubectl -n "$NS" rollout status deploy/finance-mcp --timeout=90s diff --git a/authbridge/demos/echo/Makefile b/authbridge/demos/echo/Makefile index bc68eec8a..2f2e26783 100644 --- a/authbridge/demos/echo/Makefile +++ b/authbridge/demos/echo/Makefile @@ -1,4 +1,4 @@ -# Echo demo Makefile — credential placeholder-swap, kagenti-UI flow. +# Echo demo Makefile — credential placeholder-swap, rossoctl-UI flow. # # End-to-end: # @@ -8,11 +8,11 @@ # # Unlike the IBAC demo, this demo needs a freshly-built authbridge sidecar # image: credential placeholder swap is a new authbridge capability, so we -# build the proxy from the repo root and point the kagenti platform config +# build the proxy from the repo root and point the rossoctl platform config # at the local tag before deploying the agent. # # Prerequisites: -# - kagenti installed on a kind cluster (this is the operator-flow demo) +# - rossoctl installed on a kind cluster (this is the operator-flow demo) # - kubectl, kind, podman/docker, python3 + PyYAML # - python-keycloak (for setup-keycloak; pip3 install --user python-keycloak) @@ -29,7 +29,7 @@ help: ## Show this menu (default) @printf "\nEcho demo — credential placeholder-swap, operator-injected agent in team1.\n\n" @printf "Typical run:\n" @printf " \033[1mmake demo-echo\033[0m\n" - @printf " ... chat with echo-agent in the kagenti UI ...\n" + @printf " ... chat with echo-agent in the rossoctl UI ...\n" @printf " \033[1mmake show-result\033[0m\n" @printf " \033[1mmake undeploy\033[0m\n\n" @printf "Targets:\n" @@ -37,15 +37,15 @@ help: ## Show this menu (default) /^[a-zA-Z_-]+:.*## / { printf " \033[36m%-22s\033[0m %s\n", $$1, $$2 }' \ $(MAKEFILE_LIST) @printf "\nVariables:\n" - @printf " \033[36m%-22s\033[0m %s\n" "KIND_CLUSTER_NAME" "kind cluster to load images into (default: kagenti)" + @printf " \033[36m%-22s\033[0m %s\n" "KIND_CLUSTER_NAME" "kind cluster to load images into (default: rossoctl)" @printf " \033[36m%-22s\033[0m %s\n" "NAMESPACE" "agent namespace (default: team1)" @printf " \033[36m%-22s\033[0m %s\n" "AGENT_NAME" "deployment name (default: echo-agent)" @printf " \033[36m%-22s\033[0m %s\n" "SIDECAR_IMAGE" "authbridge sidecar tag (default: authbridge:placeholder-dev)" @printf " \033[36m%-22s\033[0m %s\n" "CONTAINER_RUNTIME" "podman or docker (auto-detected)" - @printf "\nPrerequisites: kagenti install on a kind cluster, kubectl/kind/podman,\n" + @printf "\nPrerequisites: rossoctl install on a kind cluster, kubectl/kind/podman,\n" @printf "python3 + PyYAML, and python-keycloak for setup-keycloak.\n\n" -KIND_CLUSTER_NAME ?= kagenti +KIND_CLUSTER_NAME ?= rossoctl KIND_NODE ?= $(KIND_CLUSTER_NAME)-control-plane NAMESPACE ?= team1 AGENT_NAME ?= echo-agent @@ -77,15 +77,15 @@ LOAD_MARKER := $(STAMP_DIR)/.loaded-this-run # ---------- Pre-flight ---------- -preflight: ## Verify kagenti is installed + tools are available - @kubectl get ns kagenti-system >/dev/null 2>&1 || { \ - echo "ERROR: namespace 'kagenti-system' not found — kagenti doesn't appear to be installed."; \ - echo " Install kagenti first (see https://github.com/kagenti/kagenti/blob/main/docs/install.md)"; \ +preflight: ## Verify rossoctl is installed + tools are available + @kubectl get ns rossoctl-system >/dev/null 2>&1 || { \ + echo "ERROR: namespace 'rossoctl-system' not found — rossoctl doesn't appear to be installed."; \ + echo " Install rossoctl first (see https://github.com/rossoctl/rossoctl/blob/main/docs/install.md)"; \ exit 1; \ } @kubectl get ns $(NAMESPACE) >/dev/null 2>&1 || { \ - echo "ERROR: namespace '$(NAMESPACE)' not found — kagenti's agent namespace is missing."; \ - echo " Did the kagenti install complete? Try: kubectl get ns | grep team"; \ + echo "ERROR: namespace '$(NAMESPACE)' not found — rossoctl's agent namespace is missing."; \ + echo " Did the rossoctl install complete? Try: kubectl get ns | grep team"; \ exit 1; \ } @command -v kind >/dev/null 2>&1 || { echo "ERROR: kind not installed"; exit 1; } @@ -117,18 +117,18 @@ load-sidecar: ## Load the sidecar image into the kind cluster @$(CONTAINER_RUNTIME) exec $(KIND_NODE) ctr -n k8s.io images tag \ localhost/$(SIDECAR_IMAGE) docker.io/library/$(SIDECAR_IMAGE) >/dev/null 2>&1 || true -# Point the kagenti platform config at our locally-built sidecar tag so +# Point the rossoctl platform config at our locally-built sidecar tag so # the operator's injecting webhook uses it for echo-agent. We edit the # `images.authbridge` key inside the config.yaml of the -# `kagenti-platform-config` ConfigMap (kagenti-system), re-apply it, and +# `rossoctl-platform-config` ConfigMap (rossoctl-system), re-apply it, and # roll the controller so the new value is picked up. -override-sidecar-image: ## Point kagenti's platform config at the local sidecar image - @echo "[*] Overriding images.authbridge -> $(SIDECAR_IMAGE) in kagenti-platform-config ..." - @CURRENT=$$(kubectl -n kagenti-system get configmap kagenti-platform-config \ +override-sidecar-image: ## Point rossoctl's platform config at the local sidecar image + @echo "[*] Overriding images.authbridge -> $(SIDECAR_IMAGE) in rossoctl-platform-config ..." + @CURRENT=$$(kubectl -n rossoctl-system get configmap rossoctl-platform-config \ -o jsonpath='{.data.config\.yaml}'); \ if [ -z "$$CURRENT" ]; then \ - echo "ERROR: could not read config.yaml from kagenti-platform-config (kagenti-system)."; \ - echo " Is kagenti installed? kubectl -n kagenti-system get cm kagenti-platform-config"; \ + echo "ERROR: could not read config.yaml from rossoctl-platform-config (rossoctl-system)."; \ + echo " Is rossoctl installed? kubectl -n rossoctl-system get cm rossoctl-platform-config"; \ exit 1; \ fi; \ MERGED=$$(printf '%s' "$$CURRENT" | SIDECAR_IMAGE='$(SIDECAR_IMAGE)' python3 -c 'import os, sys, yaml; \ @@ -136,12 +136,12 @@ c = yaml.safe_load(sys.stdin) or {}; \ c.setdefault("images", {})["authbridge"] = os.environ["SIDECAR_IMAGE"]; \ sys.stdout.write(yaml.safe_dump(c, default_flow_style=False, sort_keys=False))'); \ TMP=$$(mktemp); printf '%s' "$$MERGED" >"$$TMP"; \ - kubectl -n kagenti-system create configmap kagenti-platform-config \ + kubectl -n rossoctl-system create configmap rossoctl-platform-config \ --from-file=config.yaml="$$TMP" --dry-run=client -o yaml | kubectl apply -f -; \ rm -f "$$TMP" - @echo "[*] Restarting the kagenti controller to pick up the new sidecar image ..." - kubectl -n kagenti-system rollout restart deploy/kagenti-controller-manager - kubectl -n kagenti-system rollout status deploy/kagenti-controller-manager --timeout=120s + @echo "[*] Restarting the rossoctl controller to pick up the new sidecar image ..." + kubectl -n rossoctl-system rollout restart deploy/rossoctl-controller-manager + kubectl -n rossoctl-system rollout status deploy/rossoctl-controller-manager --timeout=120s # ---------- Build demo images ---------- @@ -251,8 +251,8 @@ demo-echo: preflight build-sidecar load-sidecar override-sidecar-image build-ima @echo "╔══════════════════════════════════════════════════════════╗" @echo "║ ✅ Echo placeholder-swap demo agent ready ║" @echo "║ ║" - @echo "║ Open the kagenti UI: ║" - @echo "║ http://kagenti-ui.localtest.me:8080 ║" + @echo "║ Open the rossoctl UI: ║" + @echo "║ http://rossoctl-ui.localtest.me:8080 ║" @echo "║ ║" @echo "║ Log in as alice / alice123 (log out + back in if you ║" @echo "║ were already signed in — new audience scope). ║" @@ -277,7 +277,7 @@ show-result: ## Tail echo-upstream logs (the exchanged credential it received) # ---------- Cleanup ---------- -undeploy: ## Remove demo resources from team1 (kagenti install untouched) +undeploy: ## Remove demo resources from team1 (rossoctl install untouched) -kubectl -n $(NAMESPACE) delete -f k8s/agent.yaml --ignore-not-found -kubectl -n $(NAMESPACE) delete -f k8s/upstream.yaml --ignore-not-found -kubectl -n $(NAMESPACE) delete agentruntime echo-agent --ignore-not-found @@ -286,7 +286,7 @@ undeploy: ## Remove demo resources from team1 (kagenti install untouched) @echo " kubectl -n $(NAMESPACE) delete configmap authbridge-config-$(AGENT_NAME)" @rm -rf $(STAMP_DIR) @echo "[*] Demo resources removed from $(NAMESPACE)." - @echo " The kagenti install + the namespace itself are untouched." + @echo " The rossoctl install + the namespace itself are untouched." # ---------- Diagnostics ---------- diff --git a/authbridge/demos/echo/README.md b/authbridge/demos/echo/README.md index 08bea21df..c4f4c7165 100644 --- a/authbridge/demos/echo/README.md +++ b/authbridge/demos/echo/README.md @@ -6,7 +6,7 @@ still arrives at the upstream carrying a correctly **exchanged** token. ## What it proves -When you chat `echo` with the agent in the kagenti UI, the reply shows two +When you chat `echo` with the agent in the rossoctl UI, the reply shows two lines: ``` @@ -24,13 +24,13 @@ outbound: eyJhbGciOi… <- what ECHO-UPSTREAM received (aud=echo-upstre `aud=echo-upstream`. `echo-upstream` simply returns the `Authorization` header it received, giving you ground truth. -`echo-upstream` carries **no** `kagenti.io/*` labels, so the operator's webhook +`echo-upstream` carries **no** `rossoctl.io/*` labels, so the operator's webhook leaves it un-injected — what it logs is exactly what left the agent's sidecar. ## Prerequisites -- A running kagenti **kind** cluster (`kagenti-system` + `team1` namespaces). - See the [install guide](https://github.com/kagenti/kagenti/blob/main/docs/install.md). +- A running rossoctl **kind** cluster (`rossoctl-system` + `team1` namespaces). + See the [install guide](https://github.com/rossoctl/rossoctl/blob/main/docs/install.md). - `kubectl`, `kind`, `podman` or `docker`. - `python3` + PyYAML (config merge) and `python-keycloak` (Keycloak setup): `pip install pyyaml python-keycloak`. @@ -52,12 +52,12 @@ preflight → build-sidecar → load-sidecar → override-sidecar-image The placeholder-swap capability is new, so the demo builds the AuthBridge sidecar from the repo root (`build-sidecar`), loads it into kind, and points -the kagenti platform config's `images.authbridge` at the local tag +the rossoctl platform config's `images.authbridge` at the local tag (`override-sidecar-image`) before deploying the agent. ## Use it from the UI -1. Open . +1. Open . 2. Log in as **alice / alice123**. If you were already signed in, **log out and back in** — the demo adds a new audience scope to the UI client and tokens only pick it up on a fresh login. @@ -88,12 +88,12 @@ ext_proc + proxy-init iptables). To exercise it: `build-sidecar`/`override-sidecar-image`, but for `images.envoyProxy`): ```bash podman build -f ../../cmd/authbridge-envoy/Dockerfile -t authbridge-envoy:placeholder-dev ../.. - kind load docker-image authbridge-envoy:placeholder-dev --name kagenti - podman exec kagenti-control-plane ctr -n k8s.io images tag \ + kind load docker-image authbridge-envoy:placeholder-dev --name rossoctl + podman exec rossoctl-control-plane ctr -n k8s.io images tag \ localhost/authbridge-envoy:placeholder-dev docker.io/library/authbridge-envoy:placeholder-dev - # set images.envoyProxy in kagenti-system/kagenti-platform-config to + # set images.envoyProxy in rossoctl-system/rossoctl-platform-config to # authbridge-envoy:placeholder-dev, then restart the operator: - kubectl -n kagenti-system rollout restart deploy/kagenti-controller-manager + kubectl -n rossoctl-system rollout restart deploy/rossoctl-controller-manager ``` 2. Put echo-agent in envoy mode and restart so the operator re-injects Envoy + ext_proc + proxy-init: diff --git a/authbridge/demos/echo/agent/main.go b/authbridge/demos/echo/agent/main.go index dc2a95140..7a4176051 100644 --- a/authbridge/demos/echo/agent/main.go +++ b/authbridge/demos/echo/agent/main.go @@ -2,7 +2,7 @@ // // Modeled on the IBAC demo agent (authbridge/demos/ibac/agent/main.go), // keeping all the A2A / agent-card / Task scaffolding verbatim so the -// agent stays discoverable and chat-able in the kagenti UI. The IBAC +// agent stays discoverable and chat-able in the rossoctl UI. The IBAC // demo's Ollama/LLM/tool/email machinery is removed — this agent does // exactly one thing on each message/send: // @@ -156,7 +156,7 @@ type jsonRPCResponse struct { // REQUEST text on response events, which makes the agent's reply // invisible in the platform observability layer. // -// kagenti's backend chat handler accepts both shapes (chat.py:211 +// rossoctl's backend chat handler accepts both shapes (chat.py:211 // handles Task, chat.py:219 handles Message), so emitting a Task // here doesn't break the UI. type a2aTask struct { @@ -189,9 +189,9 @@ type jsonRPCError struct { } // handleAgentCard serves the A2A agent card at -// /.well-known/agent-card.json. The kagenti operator's +// /.well-known/agent-card.json. The rossoctl operator's // AgentCardReconciler fetches this URL through the agent's Service -// and stuffs the result into an AgentCard CR; the kagenti UI's agent +// and stuffs the result into an AgentCard CR; the rossoctl UI's agent // detail page renders that. Without the endpoint the UI shows // "Agent card not available." // @@ -205,7 +205,7 @@ func handleAgentCard(w http.ResponseWriter, r *http.Request) { } // AGENT_PUBLIC_URL is what the UI displays as the agent's // callable address. Defaults to the in-cluster Service URL, - // which is what kagenti UI actually uses for the chat call. + // which is what rossoctl UI actually uses for the chat call. publicURL := envOr("AGENT_PUBLIC_URL", "http://echo-agent.team1.svc.cluster.local:8080/") card := map[string]any{ "name": "Echo", @@ -285,7 +285,7 @@ func handleA2A(w http.ResponseWriter, r *http.Request) { } if sessionID == "" { // A2A spec §6.6: when the client omits a contextId, the server - // SHOULD assign one and return it. The kagenti UI currently + // SHOULD assign one and return it. The rossoctl UI currently // sends bare message/send calls without any contextId field; // returning a fresh UUID restores per-conversation bucketing // while staying backward-compatible. @@ -322,11 +322,11 @@ func runEcho(inboundAuth string) string { } // writeRPCSuccess emits an A2A v0.3.0 Task response. Both -// status.message AND artifacts carry the agent's reply: the kagenti +// status.message AND artifacts carry the agent's reply: the rossoctl // backend's chat handler reads from status.message (chat.py:211), // while the authbridge a2a-parser's response-side artifact extractor // reads from artifacts[].parts[].text (plugin.go:188-195). Carrying -// the text in both keeps the kagenti UI working AND gets the reply +// the text in both keeps the rossoctl UI working AND gets the reply // into the session-event JSON for abctl / show-result. func writeRPCSuccess(w http.ResponseWriter, id any, sessionID, text string) { taskID := newUUID() diff --git a/authbridge/demos/echo/go.mod b/authbridge/demos/echo/go.mod index 2e714edc1..ded854180 100644 --- a/authbridge/demos/echo/go.mod +++ b/authbridge/demos/echo/go.mod @@ -1,3 +1,3 @@ -module github.com/kagenti/kagenti-extensions/authbridge/demos/echo +module github.com/rossoctl/rossocortex/authbridge/demos/echo go 1.24 diff --git a/authbridge/demos/echo/k8s/agent.yaml b/authbridge/demos/echo/k8s/agent.yaml index a53efb600..0fe2c1881 100644 --- a/authbridge/demos/echo/k8s/agent.yaml +++ b/authbridge/demos/echo/k8s/agent.yaml @@ -1,14 +1,14 @@ -# Echo demo agent — operator-injected, kagenti-UI-discoverable. +# Echo demo agent — operator-injected, rossoctl-UI-discoverable. # -# Required labels for this agent to show up in the kagenti UI: -# kagenti.io/inject: enabled — operator's webhook injects authbridge -# kagenti.io/spire: disabled — demo doesn't depend on SPIRE identity -# protocol.kagenti.io/a2a: "" — declares A2A protocol for the chat flow +# Required labels for this agent to show up in the rossoctl UI: +# rossoctl.io/inject: enabled — operator's webhook injects authbridge +# rossoctl.io/spire: disabled — demo doesn't depend on SPIRE identity +# protocol.rossoctl.io/a2a: "" — declares A2A protocol for the chat flow # # The operator's webhook port-steals: it sees containerPort 8000 here, # rewrites the agent's port to 8001, and sets PORT=8001 + HTTP_PROXY so # the agent's outbound flows through the injected authbridge sidecar's -# forward proxy on :8081. Inbound traffic from the kagenti backend +# forward proxy on :8081. Inbound traffic from the rossoctl backend # hits the Service on :8080, which the operator points at the sidecar's # reverse proxy on :8000, which forwards to the agent on :8001. # @@ -37,7 +37,7 @@ metadata: # Operator's AgentCardReconciler reads this from the workload # (not the Pod template) to know what protocol to fetch the card # under and to confirm the workload is an agent. - protocol.kagenti.io/a2a: "" + protocol.rossoctl.io/a2a: "" spec: replicas: 1 selector: @@ -48,9 +48,9 @@ spec: labels: app.kubernetes.io/name: echo-agent app.kubernetes.io/part-of: echo-demo - kagenti.io/inject: enabled - kagenti.io/spire: disabled - protocol.kagenti.io/a2a: "" + rossoctl.io/inject: enabled + rossoctl.io/spire: disabled + protocol.rossoctl.io/a2a: "" spec: serviceAccountName: echo-agent securityContext: @@ -70,7 +70,7 @@ spec: - name: UPSTREAM_URL value: "http://echo-upstream.team1.svc.cluster.local:8888" # AGENT_PUBLIC_URL is what the agent advertises in its - # /.well-known/agent-card.json. The kagenti UI uses it + # /.well-known/agent-card.json. The rossoctl UI uses it # for the agent card; default below works for the # standard team1 install. - name: AGENT_PUBLIC_URL @@ -112,7 +112,7 @@ spec: selector: app.kubernetes.io/name: echo-agent # Port 8080 → targetPort 8000 mirrors the github-issue-agent demo - # shape. The kagenti backend's /chat endpoint hits the agent's + # shape. The rossoctl backend's /chat endpoint hits the agent's # Service:8080, which the operator wires to the authbridge sidecar's # reverse proxy on :8000. ports: @@ -124,11 +124,11 @@ spec: --- # AgentRuntime triggers operator-managed Keycloak client registration -# (creates kagenti-keycloak-client-credentials- Secret with +# (creates rossoctl-keycloak-client-credentials- Secret with # client-id.txt and client-secret.txt that the authbridge sidecar # mounts at /shared/). Without this CR, jwt-validation has no # audience to validate against and inbound auth falls over. -apiVersion: agent.kagenti.dev/v1alpha1 +apiVersion: agent.rossoctl.dev/v1alpha1 kind: AgentRuntime metadata: name: echo-agent @@ -146,4 +146,4 @@ spec: # admission webhook ("an AgentCard already targets Deployment X"). # The operator's CR points at the same Deployment, fetches our # `/.well-known/agent-card.json` endpoint, and stuffs the result -# into the CR's status — which the kagenti UI then displays. +# into the CR's status — which the rossoctl UI then displays. diff --git a/authbridge/demos/echo/k8s/upstream.yaml b/authbridge/demos/echo/k8s/upstream.yaml index 5ab50fb1f..da292cee1 100644 --- a/authbridge/demos/echo/k8s/upstream.yaml +++ b/authbridge/demos/echo/k8s/upstream.yaml @@ -3,7 +3,7 @@ # Returns the request's Authorization header on GET /echo. Plain HTTP # service in team1. # -# CRITICAL: this workload carries NO `kagenti.io/*` labels. That keeps +# CRITICAL: this workload carries NO `rossoctl.io/*` labels. That keeps # the operator's injecting webhook from touching it — echo-upstream must # stay a plain, un-injected "external" upstream so the demo can show the # credential the agent's authbridge sidecar produced reaching it diff --git a/authbridge/demos/echo/scripts/patch-echo-config.sh b/authbridge/demos/echo/scripts/patch-echo-config.sh index 5ace97fcc..fb65e986a 100755 --- a/authbridge/demos/echo/scripts/patch-echo-config.sh +++ b/authbridge/demos/echo/scripts/patch-echo-config.sh @@ -6,7 +6,7 @@ # # Usage: patch-echo-config.sh # -# The kagenti operator creates `authbridge-config-` when the +# The rossoctl operator creates `authbridge-config-` when the # agent's pod is admitted (server-side apply, line 682 of pod_mutator.go). # Its default pipeline has only `jwt-validation` inbound and # `token-exchange` outbound. This script: diff --git a/authbridge/demos/echo/scripts/setup_keycloak.py b/authbridge/demos/echo/scripts/setup_keycloak.py index 925539ce6..10a396ebb 100644 --- a/authbridge/demos/echo/scripts/setup_keycloak.py +++ b/authbridge/demos/echo/scripts/setup_keycloak.py @@ -32,7 +32,7 @@ Demo Users created: - alice: alice123 - bob: bob123 - (both get the realm "admin" role so the kagenti UI lists agents/tools) + (both get the realm "admin" role so the rossoctl UI lists agents/tools) Usage: python setup_keycloak.py @@ -52,7 +52,7 @@ # Default configuration KEYCLOAK_URL = os.environ.get("KEYCLOAK_URL", "http://keycloak.localtest.me:8080") -KEYCLOAK_REALM = os.environ.get("KEYCLOAK_REALM", "kagenti") +KEYCLOAK_REALM = os.environ.get("KEYCLOAK_REALM", "rossoctl") KEYCLOAK_ADMIN_USERNAME = os.environ.get("KEYCLOAK_ADMIN_USERNAME", "admin") KEYCLOAK_ADMIN_PASSWORD = os.environ.get("KEYCLOAK_ADMIN_PASSWORD", "admin") @@ -66,7 +66,7 @@ DEFAULT_NAMESPACE = "team1" DEFAULT_SERVICE_ACCOUNT = "echo-agent" SPIFFE_TRUST_DOMAIN = "localtest.me" -UI_CLIENT_ID = os.environ.get("UI_CLIENT_ID", "kagenti") +UI_CLIENT_ID = os.environ.get("UI_CLIENT_ID", "rossoctl") # The token-exchange target audience (the echo upstream). Mirrors the # `target_audience` / `token_scopes` in k8s/echo-patch.yaml's route. @@ -329,7 +329,7 @@ def main(): print(f"Note: Could not add '{ECHO_UPSTREAM_SCOPE}' as optional: {e}") # --------------------------------------------------------------- - # Add agent audience scope to the Kagenti UI client + # Add agent audience scope to the Rossoctl UI client # --------------------------------------------------------------- # Keycloak only auto-assigns realm default scopes to NEW clients. # The UI client was created during install (before this scope existed), @@ -338,7 +338,7 @@ def main(): # reject UI chat requests with "invalid audience". # # TODO: Remove this workaround once the client-registration sidecar - # handles this automatically (kagenti/kagenti-extensions#169). + # handles this automatically (rossoctl/rossocortex#169). print(f"\n--- Adding agent audience scope to UI client '{UI_CLIENT_ID}' ---") ui_client_internal_id = keycloak_admin.get_client_id(UI_CLIENT_ID) if ui_client_internal_id: @@ -399,7 +399,7 @@ def main(): print(f"\n {user['username']}: {user['description']}") get_or_create_user(keycloak_admin, user) - # The Kagenti backend uses the "admin" realm role for RBAC. Without + # The Rossoctl backend uses the "admin" realm role for RBAC. Without # it, users can log in but see no agents or tools in the UI. print("\n--- Assigning 'admin' realm role to demo users ---") try: @@ -417,7 +417,7 @@ def main(): else: print( "Warning: 'admin' realm role not found. Demo users will not " - "be able to see agents/tools in the UI. Ensure the Kagenti " + "be able to see agents/tools in the UI. Ensure the Rossoctl " "platform is installed before running this script." ) diff --git a/authbridge/demos/finance-sparc/Makefile b/authbridge/demos/finance-sparc/Makefile index 2b1c0fdff..7539b60e0 100644 --- a/authbridge/demos/finance-sparc/Makefile +++ b/authbridge/demos/finance-sparc/Makefile @@ -10,7 +10,7 @@ # pipeline, configures Keycloak, and drives the two-turn scenario through REAL # inbound auth (no jwt bypass), printing SPARC's verdicts. # -# Prereqs: a kagenti kind cluster, Ollama on the host with the model, and +# Prereqs: a rossoctl kind cluster, Ollama on the host with the model, and # kubectl / kind / docker(or podman) / python3 / uv. For PROVIDER=watsonx also # export WX_API_KEY and WX_PROJECT_ID (e.g. `set -a; . /path/.env; set +a`). @@ -21,17 +21,17 @@ .DEFAULT_GOAL := help PROVIDER ?= watsonx -KIND_CLUSTER_NAME ?= kagenti +KIND_CLUSTER_NAME ?= rossoctl KIND_NODE := $(KIND_CLUSTER_NAME)-control-plane # NS / AGENT / PLATFORM_NS are fixed: the k8s/ manifests hardcode these names -# (team1 / finance-agent / kagenti-system), so they are not override knobs — +# (team1 / finance-agent / rossoctl-system), so they are not override knobs — # changing them here alone would target resources the manifests never create. NS := team1 AGENT := finance-agent -PLATFORM_NS := kagenti-system +PLATFORM_NS := rossoctl-system # Prefer whichever runtime's daemon is actually reachable (docker first). CONTAINER_RUNTIME ?= $(shell docker info >/dev/null 2>&1 && echo docker || (podman info >/dev/null 2>&1 && echo podman) || echo docker) -AUTHBRIDGE_IMAGE ?= ghcr.io/kagenti/kagenti-extensions/authbridge:v0.6.0-alpha.4 +AUTHBRIDGE_IMAGE ?= ghcr.io/rossoctl/rossocortex/authbridge:v0.6.0-alpha.4 AGENT_IMAGE := finance-agent:latest MCP_IMAGE := finance-mcp:latest @@ -79,8 +79,8 @@ help: ## Show this menu @awk 'BEGIN{FS=":.*## "} /^[a-zA-Z_-]+:.*## /{printf " \033[36m%-16s\033[0m %s\n",$$1,$$2}' $(MAKEFILE_LIST) @printf "\nVars: PROVIDER(=%s) KIND_CLUSTER_NAME AUTHBRIDGE_IMAGE SPARC_MODEL HOST_OLLAMA_URL\n\n" "$(PROVIDER)" -preflight: ## Verify kagenti + tools (+ watsonx creds when PROVIDER=watsonx) - @kubectl get ns $(PLATFORM_NS) >/dev/null 2>&1 || { echo "ERROR: '$(PLATFORM_NS)' not found — install kagenti first."; exit 1; } +preflight: ## Verify rossoctl + tools (+ watsonx creds when PROVIDER=watsonx) + @kubectl get ns $(PLATFORM_NS) >/dev/null 2>&1 || { echo "ERROR: '$(PLATFORM_NS)' not found — install rossoctl first."; exit 1; } @kubectl get ns $(NS) >/dev/null 2>&1 || { echo "ERROR: agent namespace '$(NS)' not found."; exit 1; } @for t in kubectl kind python3 uv; do command -v $$t >/dev/null 2>&1 || { echo "ERROR: $$t not installed"; exit 1; }; done @if [ "$(PROVIDER)" = "watsonx" ]; then \ @@ -172,7 +172,7 @@ drive: ## Drive the two-turn scenario through real auth and print SPARC verdict demo: preflight host-setup load-images ollama-up deploy patch-config setup-keycloak drive ## Full end-to-end demo @echo - @echo "Demo complete. UI: http://kagenti-ui.localtest.me:8080 | forensic: make show-result" + @echo "Demo complete. UI: http://rossoctl-ui.localtest.me:8080 | forensic: make show-result" build-abctl: ## Build abctl into /tmp (for show-result) cd ../../cmd/abctl && go build -o /tmp/abctl-finance-sparc-demo . @@ -180,13 +180,13 @@ build-abctl: ## Build abctl into /tmp (for show-result) show-result: build-abctl ## Launch abctl against the agent's session API bash scripts/launch-abctl.sh $(NS) $(AGENT) -undeploy: ## Remove demo resources (kagenti install untouched) +undeploy: ## Remove demo resources (rossoctl install untouched) -kubectl -n $(NS) delete -f k8s/agent.yaml --ignore-not-found -kubectl -n $(NS) delete -f k8s/finance-mcp.yaml --ignore-not-found -kubectl -n $(NS) delete -f k8s/ollama.yaml --ignore-not-found -$(MAKE) -C $(SPARC_DEPLOY) uninstall NAMESPACE=$(PLATFORM_NS) -kubectl -n $(NS) delete configmap authbridge-config-$(AGENT) --ignore-not-found - -kubectl -n $(NS) delete secret -l kagenti.io/client-name=$(AGENT) --ignore-not-found + -kubectl -n $(NS) delete secret -l rossoctl.io/client-name=$(AGENT) --ignore-not-found @echo "[*] demo resources removed." logs-agent: ## Tail agent + authbridge sidecar logs diff --git a/authbridge/demos/finance-sparc/README.md b/authbridge/demos/finance-sparc/README.md index 5c6fe1f7c..5ee7cebba 100644 --- a/authbridge/demos/finance-sparc/README.md +++ b/authbridge/demos/finance-sparc/README.md @@ -5,7 +5,7 @@ hallucinated tool argument before it executes. SPARC's clarification is returned as an MCP tool result, so the agent asks the user for the missing detail and then runs the corrected call. -The agent is an ordinary kagenti agent: it discovers its tools via MCP `tools/list`, reasons +The agent is an ordinary rossoctl agent: it discovers its tools via MCP `tools/list`, reasons with an Ollama model, and acts through an MCP finance backend. SPARC only sees what the agent itself produces — the full conversation (including the system prompt), the discovered tool specs in OpenAI format, and the proposed tool call. Those are collected by the parsers from the @@ -33,10 +33,10 @@ SPARC allow/grounded tool=issue_refund score=1.00 # Turn 2: grounded TX482 ## Prerequisites -- A **kagenti kind cluster** with the AuthBridge operator. Core + SPIRE is enough: +- A **rossoctl kind cluster** with the AuthBridge operator. Core + SPIRE is enough: ```bash - # from the kagenti repo: - scripts/kind/setup-kagenti.sh --with-spire + # from the rossoctl repo: + scripts/kind/setup-rossoctl.sh --with-spire ``` - `kubectl`, `kind`, `docker` (or `podman`), `python3`, `uv`. - **Ollama models.** What you need depends on the reflection provider: @@ -98,7 +98,7 @@ inbound auth** (no jwt bypass), printing SPARC's verdicts. make logs-agent # agent + authbridge sidecar logs ``` - **Re-run just the conversation** (cluster already set up): `make drive`. -- **Tear down the demo** (kagenti install untouched): `make undeploy`. +- **Tear down the demo** (rossoctl install untouched): `make undeploy`. ## How it works (and why it's generic) @@ -158,11 +158,11 @@ inbound auth** (no jwt bypass), printing SPARC's verdicts. container runtime's VM resolver went stale after a network change (common with Docker Desktop / Rancher Desktop / colima after switching Wi-Fi or VPN). Restart the runtime, or point its VM and the kind node at a public resolver (`8.8.8.8`). This is a host-runtime issue, - not a demo or kagenti one — the demo scripts contain no machine-specific networking. + not a demo or rossoctl one — the demo scripts contain no machine-specific networking. - **`authbridge-config-` reverted to defaults**: the operator rewrites it whenever the agent pod rolls. `make demo` (and `make patch-config`) re-apply the SPARC pipeline and wait for the live config SHA to converge, so just re-run the relevant target. -- **Agent pods stuck `ContainerCreating` on a missing `kagenti-keycloak-client-credentials-*` +- **Agent pods stuck `ContainerCreating` on a missing `rossoctl-keycloak-client-credentials-*` secret** (operator log: *"waiting for KEYCLOAK_URL/KEYCLOAK_REALM in authbridge-config"* or *"waiting for keycloak-admin-secret"*): a platform/operator-version skew — the operator registers the agent's Keycloak client from resources a matching chart version provides. This @@ -170,12 +170,12 @@ inbound auth** (no jwt bypass), printing SPARC's verdicts. ```bash kubectl -n team1 create configmap authbridge-config \ --from-literal=KEYCLOAK_URL=http://keycloak-service.keycloak:8080 \ - --from-literal=KEYCLOAK_REALM=kagenti --dry-run=client -o yaml | kubectl apply -f - - kubectl -n kagenti-system create secret generic keycloak-admin-secret \ + --from-literal=KEYCLOAK_REALM=rossoctl --dry-run=client -o yaml | kubectl apply -f - + kubectl -n rossoctl-system create secret generic keycloak-admin-secret \ --from-literal=KEYCLOAK_ADMIN_USERNAME=admin \ --from-literal=KEYCLOAK_ADMIN_PASSWORD=admin --dry-run=client -o yaml | kubectl apply -f - ``` - A kagenti install whose chart and operator versions are aligned creates these automatically. + A rossoctl install whose chart and operator versions are aligned creates these automatically. - **`PROVIDER=ollama`: `reflector_unavailable` / can't reach the host Ollama**: the cluster must reach your host Ollama. Run it with `OLLAMA_HOST=0.0.0.0`, and set `HOST_OLLAMA_URL` correctly (Docker Desktop: `http://host.docker.internal:11434`; Rancher Desktop / colima: diff --git a/authbridge/demos/finance-sparc/finance-agent/main.go b/authbridge/demos/finance-sparc/finance-agent/main.go index 33c5cc3ed..4f3a1fbd3 100644 --- a/authbridge/demos/finance-sparc/finance-agent/main.go +++ b/authbridge/demos/finance-sparc/finance-agent/main.go @@ -1,6 +1,6 @@ // Finance assistant agent for the SPARC demo. // -// A regular kagenti A2A agent (JSON-RPC over HTTP at /). It reasons with a +// A regular rossoctl A2A agent (JSON-RPC over HTTP at /). It reasons with a // local Ollama model and acts through a finance MCP server. It DISCOVERS its // tools at runtime via MCP `tools/list` — nothing about the tools is hardcoded // — so it behaves like any normal agent. There is no demo-specific steering or diff --git a/authbridge/demos/finance-sparc/finance-mcp/main.go b/authbridge/demos/finance-sparc/finance-mcp/main.go index c1009f67e..a62d85860 100644 --- a/authbridge/demos/finance-sparc/finance-mcp/main.go +++ b/authbridge/demos/finance-sparc/finance-mcp/main.go @@ -3,7 +3,7 @@ // Speaks MCP (Model Context Protocol) over HTTP — JSON-RPC 2.0 POSTs to /mcp. // Serves a small but non-trivial finance dataset through five tools and // advertises them via tools/list (so the agent discovers them at runtime like -// any normal kagenti agent — nothing is hardcoded on the agent side). +// any normal rossoctl agent — nothing is hardcoded on the agent side). // // Tools: // diff --git a/authbridge/demos/finance-sparc/go.mod b/authbridge/demos/finance-sparc/go.mod index d4bebc7cc..b58248ab7 100644 --- a/authbridge/demos/finance-sparc/go.mod +++ b/authbridge/demos/finance-sparc/go.mod @@ -1,3 +1,3 @@ -module github.com/kagenti/kagenti-extensions/authbridge/demos/finance-sparc +module github.com/rossoctl/rossocortex/authbridge/demos/finance-sparc go 1.24 diff --git a/authbridge/demos/finance-sparc/k8s/agent.yaml b/authbridge/demos/finance-sparc/k8s/agent.yaml index 740768056..94fd3a13d 100644 --- a/authbridge/demos/finance-sparc/k8s/agent.yaml +++ b/authbridge/demos/finance-sparc/k8s/agent.yaml @@ -1,9 +1,9 @@ -# finance-sparc demo agent — operator-injected, kagenti-UI-discoverable. +# finance-sparc demo agent — operator-injected, rossoctl-UI-discoverable. # # Required labels (same contract as demos/ibac/k8s/agent.yaml): -# kagenti.io/inject: enabled — operator's webhook injects authbridge -# kagenti.io/spire: disabled — demo doesn't depend on SPIRE identity -# protocol.kagenti.io/a2a: "" — declares A2A for the chat flow +# rossoctl.io/inject: enabled — operator's webhook injects authbridge +# rossoctl.io/spire: disabled — demo doesn't depend on SPIRE identity +# protocol.rossoctl.io/a2a: "" — declares A2A for the chat flow # # The operator port-steals (containerPort 8000 → agent on 8001, PORT and # HTTP_PROXY set so outbound flows through the injected sidecar's forward @@ -24,7 +24,7 @@ metadata: labels: app.kubernetes.io/name: finance-agent app.kubernetes.io/part-of: finance-sparc-demo - protocol.kagenti.io/a2a: "" + protocol.rossoctl.io/a2a: "" spec: replicas: 1 selector: @@ -35,9 +35,9 @@ spec: labels: app.kubernetes.io/name: finance-agent app.kubernetes.io/part-of: finance-sparc-demo - kagenti.io/inject: enabled - kagenti.io/spire: disabled - protocol.kagenti.io/a2a: "" + rossoctl.io/inject: enabled + rossoctl.io/spire: disabled + protocol.rossoctl.io/a2a: "" spec: serviceAccountName: finance-agent securityContext: @@ -105,7 +105,7 @@ spec: # AgentRuntime triggers operator-managed Keycloak client registration # (the Secret the authbridge sidecar mounts at /shared/) and auto-creation # of an AgentCard CR for the agent deployment. -apiVersion: agent.kagenti.dev/v1alpha1 +apiVersion: agent.rossoctl.dev/v1alpha1 kind: AgentRuntime metadata: name: finance-agent diff --git a/authbridge/demos/finance-sparc/k8s/ollama.yaml b/authbridge/demos/finance-sparc/k8s/ollama.yaml index dc1f4fecf..c379dbf18 100644 --- a/authbridge/demos/finance-sparc/k8s/ollama.yaml +++ b/authbridge/demos/finance-sparc/k8s/ollama.yaml @@ -21,7 +21,7 @@ spec: labels: app.kubernetes.io/name: ollama app.kubernetes.io/part-of: finance-sparc-demo - kagenti.io/inject: disabled + rossoctl.io/inject: disabled spec: securityContext: runAsNonRoot: true diff --git a/authbridge/demos/finance-sparc/k8s/sparc-patch.yaml b/authbridge/demos/finance-sparc/k8s/sparc-patch.yaml index 5a5e5927a..31a56bc5a 100644 --- a/authbridge/demos/finance-sparc/k8s/sparc-patch.yaml +++ b/authbridge/demos/finance-sparc/k8s/sparc-patch.yaml @@ -24,7 +24,7 @@ outbound_append: reflector_endpoint: "${SPARC_REFLECTOR_ENDPOINT}" # Gate the MCP tools/call and return the clarification as an MCP tool - # result (the kagenti norm). Use "inference" for non-MCP agents. + # result (the rossoctl norm). Use "inference" for non-MCP agents. enforcement: "mcp" # fast_track = hallucination + function-selection checks. diff --git a/authbridge/demos/finance-sparc/scripts/drive-demo.sh b/authbridge/demos/finance-sparc/scripts/drive-demo.sh index 10427a3ae..ee69ef123 100644 --- a/authbridge/demos/finance-sparc/scripts/drive-demo.sh +++ b/authbridge/demos/finance-sparc/scripts/drive-demo.sh @@ -9,7 +9,7 @@ set -euo pipefail NS=${1:-team1} AGENT=${2:-finance-agent} -REALM=${KEYCLOAK_REALM:-kagenti} +REALM=${KEYCLOAK_REALM:-rossoctl} ROPC_CLIENT_ID=${ROPC_CLIENT_ID:-finance-sparc-e2e} USER=${DEMO_USER:-alice} PASS=${DEMO_PASS:-alice123} diff --git a/authbridge/demos/finance-sparc/scripts/host-setup.sh b/authbridge/demos/finance-sparc/scripts/host-setup.sh index 908eb5c5f..75ff8b513 100644 --- a/authbridge/demos/finance-sparc/scripts/host-setup.sh +++ b/authbridge/demos/finance-sparc/scripts/host-setup.sh @@ -16,7 +16,7 @@ # so no host-Ollama reachability or host networking is required. set -euo pipefail -CLUSTER=${KIND_CLUSTER_NAME:-kagenti} +CLUSTER=${KIND_CLUSTER_NAME:-rossoctl} NODE="${CLUSTER}-control-plane" PROBE_URL=${EGRESS_PROBE_URL:-https://us-south.ml.cloud.ibm.com} say() { printf '\033[1m%s\033[0m\n' "$*"; } diff --git a/authbridge/demos/finance-sparc/scripts/patch-sparc-config.sh b/authbridge/demos/finance-sparc/scripts/patch-sparc-config.sh index a1845f486..d0a33716b 100644 --- a/authbridge/demos/finance-sparc/scripts/patch-sparc-config.sh +++ b/authbridge/demos/finance-sparc/scripts/patch-sparc-config.sh @@ -5,7 +5,7 @@ # # Usage: patch-sparc-config.sh # -# The kagenti operator creates `authbridge-config-` when the agent +# The rossoctl operator creates `authbridge-config-` when the agent # pod is admitted (default pipeline: jwt-validation inbound, token-exchange # outbound). This script extracts that config, merges k8s/sparc-patch.yaml # via scripts/pipeline-merge.py, re-applies it, and blocks until the @@ -33,7 +33,7 @@ fi # Render ${...} placeholders in the patch fragment (provider-tunable knobs). # Defaults keep watsonx behavior identical to before. SPARC_TIMEOUT_MS=${SPARC_TIMEOUT_MS:-30000} -SPARC_REFLECTOR_ENDPOINT=${SPARC_REFLECTOR_ENDPOINT:-http://sparc-service.kagenti-system.svc.cluster.local:8090} +SPARC_REFLECTOR_ENDPOINT=${SPARC_REFLECTOR_ENDPOINT:-http://sparc-service.rossoctl-system.svc.cluster.local:8090} RENDERED_PATCH=$(mktemp) trap 'rm -f "$RENDERED_PATCH"' EXIT sed -e "s|\${SPARC_TIMEOUT_MS}|${SPARC_TIMEOUT_MS}|g" \ diff --git a/authbridge/demos/finance-sparc/scripts/setup_keycloak_finance.py b/authbridge/demos/finance-sparc/scripts/setup_keycloak_finance.py index 2aafc1b0b..4b94dbeee 100644 --- a/authbridge/demos/finance-sparc/scripts/setup_keycloak_finance.py +++ b/authbridge/demos/finance-sparc/scripts/setup_keycloak_finance.py @@ -2,7 +2,7 @@ """Keycloak setup for the finance-sparc demo. Makes the finance-agent's inbound jwt-validation pass for tokens minted by the -demo (scripted ROPC) and by the kagenti UI, by creating an audience client +demo (scripted ROPC) and by the rossoctl UI, by creating an audience client scope that puts the agent's SPIFFE id in the token `aud`, and a public direct-access (ROPC) client + a demo user `alice`. @@ -16,10 +16,10 @@ from keycloak import KeycloakAdmin KEYCLOAK_URL = os.environ.get("KEYCLOAK_URL", "http://keycloak.localtest.me:8080") -KEYCLOAK_REALM = os.environ.get("KEYCLOAK_REALM", "kagenti") +KEYCLOAK_REALM = os.environ.get("KEYCLOAK_REALM", "rossoctl") ADMIN_USER = os.environ.get("KEYCLOAK_ADMIN_USERNAME", "admin") ADMIN_PASS = os.environ.get("KEYCLOAK_ADMIN_PASSWORD", "admin") -UI_CLIENT_ID = os.environ.get("UI_CLIENT_ID", "kagenti") +UI_CLIENT_ID = os.environ.get("UI_CLIENT_ID", "rossoctl") SPIFFE_TRUST_DOMAIN = os.environ.get("SPIFFE_TRUST_DOMAIN", "localtest.me") NAMESPACE = os.environ.get("NAMESPACE", "team1") AGENT_SA = os.environ.get("AGENT_SA", "finance-agent") diff --git a/authbridge/demos/finance-sparc/scripts/stage-ollama-model.sh b/authbridge/demos/finance-sparc/scripts/stage-ollama-model.sh index 54bd13fb4..c46fbba04 100644 --- a/authbridge/demos/finance-sparc/scripts/stage-ollama-model.sh +++ b/authbridge/demos/finance-sparc/scripts/stage-ollama-model.sh @@ -8,7 +8,7 @@ set -euo pipefail MODEL=${1:-${OLLAMA_MODEL:-llama3.2:3b}} -CLUSTER=${KIND_CLUSTER_NAME:-kagenti} +CLUSTER=${KIND_CLUSTER_NAME:-rossoctl} NODE="${CLUSTER}-control-plane" STORE="${OLLAMA_MODELS_DIR:-$HOME/.ollama/models}" REPO="${MODEL%%:*}"; TAG="${MODEL##*:}" diff --git a/authbridge/demos/github-issue/aiac/Makefile b/authbridge/demos/github-issue/aiac/Makefile index c8010b52b..4b19918b7 100644 --- a/authbridge/demos/github-issue/aiac/Makefile +++ b/authbridge/demos/github-issue/aiac/Makefile @@ -32,7 +32,7 @@ help: ## Show this menu (default) @printf "\nVariables:\n" @printf " \033[36m%-20s\033[0m %s\n" "POLICY" "policy file to apply (default: policies/regular_policy.txt)" @printf " \033[36m%-20s\033[0m %s\n" "RBAC_CONFIG" "RBAC config file (default: rbac/config.yaml)" - @printf " \033[36m%-20s\033[0m %s\n" "PYTHON" "Python interpreter (default: kagenti-extensions/.venv/bin/python)" + @printf " \033[36m%-20s\033[0m %s\n" "PYTHON" "Python interpreter (default: rossocortex/.venv/bin/python)" @printf "\nPrerequisites: uv, Keycloak running, aiac.env and llm_conf.yaml configured.\n\n" POLICY ?= policies/regular_policy.txt diff --git a/authbridge/demos/github-issue/aiac/aiac.env.TEMPLATE b/authbridge/demos/github-issue/aiac/aiac.env.TEMPLATE index 21d1b53c7..ffa4fcb1f 100644 --- a/authbridge/demos/github-issue/aiac/aiac.env.TEMPLATE +++ b/authbridge/demos/github-issue/aiac/aiac.env.TEMPLATE @@ -3,4 +3,4 @@ KEYCLOAK_URL=http://keycloak.localtest.me:8080 KEYCLOAK_ADMIN_USERNAME= KEYCLOAK_ADMIN_PASSWORD= -REALM_NAME=kagenti +REALM_NAME=rossoctl diff --git a/authbridge/demos/github-issue/aiac/aiac_agent/utils/validators.py b/authbridge/demos/github-issue/aiac/aiac_agent/utils/validators.py index 42af90ebd..57c2e6325 100644 --- a/authbridge/demos/github-issue/aiac/aiac_agent/utils/validators.py +++ b/authbridge/demos/github-issue/aiac/aiac_agent/utils/validators.py @@ -210,7 +210,7 @@ def verify_policy_semantics( 2. CLIENT ROLES (Permissions): - Only validate roles that exist in "AVAILABLE CLIENT ROLES" above - - Call-chain/infrastructure roles (kagenti, spiffe) are ALWAYS required - ignore them in validation + - Call-chain/infrastructure roles (rossoctl, spiffe) are ALWAYS required - ignore them in validation - Focus ONLY on the final target client roles (e.g., github-tool roles) - CRITICAL: Roles are COMPLETELY INDEPENDENT - one role does NOT include another - Role names are misleading - "full-access" does NOT automatically include other roles @@ -229,7 +229,7 @@ def verify_policy_semantics( - Answer: YES or NO Q2: Are the client roles correctly mapped for the final target? -- Ignore call-chain roles (kagenti, spiffe) - they're infrastructure +- Ignore call-chain roles (rossoctl, spiffe) - they're infrastructure - Check ONLY the final target roles (e.g., github-tool roles) against the description - If description says "both X and Y", check that BOTH roles appear in the comma-separated list - If description says "only X", check that ONLY X appears (not Y) diff --git a/authbridge/demos/github-issue/aiac/scripts/show-result.py b/authbridge/demos/github-issue/aiac/scripts/show-result.py index 1c46d029d..11f22651c 100644 --- a/authbridge/demos/github-issue/aiac/scripts/show-result.py +++ b/authbridge/demos/github-issue/aiac/scripts/show-result.py @@ -23,7 +23,7 @@ load_dotenv(dotenv_path=AIAC_DIR / "aiac.env", override=True) -REALM = os.getenv("REALM_NAME", "kagenti") +REALM = os.getenv("REALM_NAME", "rossoctl") KEYCLOAK_URL = os.getenv("KEYCLOAK_URL") KEYCLOAK_USER = os.getenv("KEYCLOAK_ADMIN_USERNAME") KEYCLOAK_PASS = os.getenv("KEYCLOAK_ADMIN_PASSWORD") diff --git a/authbridge/demos/github-issue/demo-aiac.md b/authbridge/demos/github-issue/demo-aiac.md index 0e8204062..11f6dc88d 100644 --- a/authbridge/demos/github-issue/demo-aiac.md +++ b/authbridge/demos/github-issue/demo-aiac.md @@ -74,7 +74,7 @@ Before starting, ensure you have: - Python 3.9+ with `venv` support - Keycloak running and accessible -- The kagenti-extensions repository cloned +- The rossocortex repository cloned - Basic understanding of Keycloak concepts (realms, clients, roles) **Creating GitHub Personal Access Tokens** @@ -93,16 +93,16 @@ The agent and tool container images must be built locally and loaded into the ki cd /agent-examples # Build the GitHub tool image -docker build -t ghcr.io/kagenti/agent-examples/github-tool:latest \ +docker build -t ghcr.io/rossoctl/examples/github-tool:latest \ -f mcp/github_tool/Dockerfile mcp/github_tool/ # Build the GitHub Issue Agent image -docker build -t ghcr.io/kagenti/agent-examples/git-issue-agent:latest \ +docker build -t ghcr.io/rossoctl/examples/git-issue-agent:latest \ -f a2a/git_issue_agent/Dockerfile a2a/git_issue_agent/ # Load both images into the kind cluster -kind load docker-image --name kagenti ghcr.io/kagenti/agent-examples/github-tool:latest -kind load docker-image --name kagenti ghcr.io/kagenti/agent-examples/git-issue-agent:latest +kind load docker-image --name rossoctl ghcr.io/rossoctl/examples/github-tool:latest +kind load docker-image --name rossoctl ghcr.io/rossoctl/examples/git-issue-agent:latest ``` ### Step 1: Environment Setup @@ -110,7 +110,7 @@ kind load docker-image --name kagenti ghcr.io/kagenti/agent-examples/git-issue-a Create and activate a Python virtual environment: ```bash -cd kagenti-extensions/ +cd rossocortex/ # Create virtual environment uv sync @@ -125,12 +125,12 @@ uv pip install -r requirements.txt ### Step 2: Apply Demo ConfigMaps -The Kagenti installer creates default ConfigMaps. +The Rossoctl installer creates default ConfigMaps. Apply the demo-specific ConfigMaps — the `authproxy-routes` ConfigMap configures per-route token exchange (target audience and scopes for the `github-tool` host), and `authbridge-config` sets the agent SPIFFE ID for inbound audience validation. Apply this **before** deploying the agent. ```bash -cd kagenti-extensions/authbridge +cd rossocortex/authbridge # Create namespace if it doesn't exist kubectl create namespace team1 --dry-run=client -o yaml | kubectl apply -f - @@ -249,18 +249,18 @@ kubectl get pod -n team1 -l app.kubernetes.io/name=git-issue-agent \ -o jsonpath='{.items[0].spec.volumes[?(@.secret)].secret.secretName}' ``` -Expected: A Secret name starting with `kagenti-keycloak-client-credentials-....` +Expected: A Secret name starting with `rossoctl-keycloak-client-credentials-....` **Follow the operator-side registration:** ```bash -kubectl logs deployment/kagenti-controller-manager -n kagenti-system \ +kubectl logs deployment/rossoctl-controller-manager -n rossoctl-system \ | grep -iE "clientregistration|git-issue-agent" | tail -20 ``` Expected (operator log lines): ``` -{"level":"info","ts":"2026-06-16T18:14:20Z","msg":"operator client registration applied","controller":"clientregistration","controllerGroup":"apps","controllerKind":"Deployment","Deployment":{"name":"git-issue-agent","namespace":"team1"},"namespace":"team1","name":"git-issue-agent","reconcileID":"d4654c2c-7bcd-4596-8277-c643b550d70d","workload":"git-issue-agent","namespace":"team1","secret":"kagenti-keycloak-client-credentials-352ed374f36956bc"} +{"level":"info","ts":"2026-06-16T18:14:20Z","msg":"operator client registration applied","controller":"clientregistration","controllerGroup":"apps","controllerKind":"Deployment","Deployment":{"name":"git-issue-agent","namespace":"team1"},"namespace":"team1","name":"git-issue-agent","reconcileID":"d4654c2c-7bcd-4596-8277-c643b550d70d","workload":"git-issue-agent","namespace":"team1","secret":"rossoctl-keycloak-client-credentials-352ed374f36956bc"} ``` #### Check agent logs @@ -365,7 +365,7 @@ update the required values e.g.: KEYCLOAK_URL=http://keycloak.localtest.me:8080 KEYCLOAK_ADMIN_USERNAME=admin KEYCLOAK_ADMIN_PASSWORD= -REALM_NAME=kagenti +REALM_NAME=rossoctl ``` #### LLM Configuration @@ -387,14 +387,14 @@ kubectl exec -it test-client -n team1 -- bash ``` ⚠️ NOTE ⚠️ -Inside the test pod, verify the Keycloak users credentials are set properly before moving forward. If needed, fix credentials manually via the UI ONLY in kagenti realm: +Inside the test pod, verify the Keycloak users credentials are set properly before moving forward. If needed, fix credentials manually via the UI ONLY in rossoctl realm: This creates: | Resource | Name | Purpose | |----------|------|---------| -| **Realm** | `kagenti` | Keycloak realm for the demo | +| **Realm** | `rossoctl` | Keycloak realm for the demo | | **Clients** | `git-issue-agent`, `github-tool` | Service clients with roles | | **Realm Roles** | `developer`, `sales`, `tech-support` | User roles | | **Users** | `alice`, `bob`, `charlie` | Demo users with different roles | @@ -413,7 +413,7 @@ Authbridge outbound check will exchange the token, then deny the request since t ```bash -REALM_NAME="kagenti" +REALM_NAME="rossoctl" ADMIN_TOKEN=$(curl -s http://keycloak-service.keycloak.svc:8080/realms/${REALM_NAME}/protocol/openid-connect/token \ -d "grant_type=password" \ @@ -455,7 +455,7 @@ curl -s --max-time 300 \ "message": { "role": "user", "messageId": "msg-alice-pub-1", - "parts": [{"type": "text", "text": "List one issue in kagenti/kagenti repo"}] + "parts": [{"type": "text", "text": "List one issue in rossoctl/rossoctl repo"}] } } }' | jq '.result.artifacts[0].parts[0].text' | head -5 @@ -494,7 +494,7 @@ curl -s --max-time 300 \ "message": { "role": "user", "messageId": "msg-bob-pub-1", - "parts": [{"type": "text", "text": "List one issue in kagenti/kagenti repoo"}] + "parts": [{"type": "text", "text": "List one issue in rossoctl/rossoctl repoo"}] } } }' | jq '.result.artifacts[0].parts[0].text' | head -5 @@ -509,7 +509,7 @@ Verify $ADMIN_TOKEN is not empty (Keycloak reachable?) and that setup_keycloak.p You can also list all clients with: \ -`curl -s -H "Authorization: Bearer $ADMIN_TOKEN" "http://keycloak-service.keycloak.svc:8080/admin/realms/kagenti/clients" | jq '.[].clientId'` +`curl -s -H "Authorization: Bearer $ADMIN_TOKEN" "http://keycloak-service.keycloak.svc:8080/admin/realms/rossoctl/clients" | jq '.[].clientId'` @@ -611,7 +611,7 @@ You can verify the applied policy in the Keycloak admin console: 1. Open Keycloak admin console: `http://keycloak.localtest.me:8080/` 2. Login with admin credentials -3. Select the `kagenti` realm +3. Select the `rossoctl` realm 4. Navigate to **Realm roles** 5. Click on a role (e.g., `developer` or `tech-support`) 6. Go to the **Composite roles** tab @@ -626,7 +626,7 @@ Test the policy by getting tokens for different users: ```bash -REALM_NAME="kagenti" +REALM_NAME="rossoctl" ADMIN_TOKEN=$(curl -s http://keycloak-service.keycloak.svc:8080/realms/${REALM_NAME}/protocol/openid-connect/token \ -d "grant_type=password" \ @@ -647,7 +647,7 @@ echo "Client ID: $CLIENT_ID Secret length: ${#CLIENT_SECRET}" # step 2 - run AIAC using regualr policy # python aiac_cli.py policies/regular_policy.txt # users will be configured acording to the 'regular' policy -#ALICE (Developer) can list issues in kagenti/kagenti repo +#ALICE (Developer) can list issues in rossoctl/rossoctl repo #ALICE can also list issues in omerboehm/intro2c repo (because she is a DEVELOPER and has full access) ALICE_TOKEN=$(curl -s -X POST \ @@ -671,7 +671,7 @@ curl -s --max-time 300 \ "message": { "role": "user", "messageId": "msg-alice-pub-2", - "parts": [{"type": "text", "text": "List issues in kagenti/kagenti repo"}] + "parts": [{"type": "text", "text": "List issues in rossoctl/rossoctl repo"}] } } }' | jq '.result.artifacts[0].parts[0].text' | head -5 @@ -694,7 +694,7 @@ curl -s --max-time 300 \ } }' | jq '.result.artifacts[0].parts[0].text' | head -5 -#BOB (tech-support) can list issues in kagenti/kagenti repo +#BOB (tech-support) can list issues in rossoctl/rossoctl repo #BOB can not list issues in omerboehm/intro2c repo (because he is a TechSupport and has public access) BOB_TOKEN=$(curl -s -X POST \ @@ -721,7 +721,7 @@ curl -s --max-time 300 \ "message": { "role": "user", "messageId": "msg-bob-pub-2", - "parts": [{"type": "text", "text": "List one issue in kagenti/kagenti repo"}] + "parts": [{"type": "text", "text": "List one issue in rossoctl/rossoctl repo"}] } } }' | jq '.result.artifacts[0].parts[0].text' | head -5 @@ -745,7 +745,7 @@ curl -s --max-time 300 \ }' | jq '.result.artifacts[0].parts[0].text' | head -5 -#Charlie (Sales) still cannot list issues in kagenti/kagenti repo (Role Sales in policy doesnt allow) +#Charlie (Sales) still cannot list issues in rossoctl/rossoctl repo (Role Sales in policy doesnt allow) CHARLIE_TOKEN=$(curl -s -X POST \ @@ -769,7 +769,7 @@ curl -s --max-time 300 \ "message": { "role": "user", "messageId": "msg-charlie-pub-1", - "parts": [{"type": "text", "text": "List one issue in kagenti/kagenti repo"}] + "parts": [{"type": "text", "text": "List one issue in rossoctl/rossoctl repo"}] } } }' | jq '.result.artifacts[0].parts[0].text' | head -5 diff --git a/authbridge/demos/github-issue/demo-manual.md b/authbridge/demos/github-issue/demo-manual.md index fde1edef6..4f3e45960 100644 --- a/authbridge/demos/github-issue/demo-manual.md +++ b/authbridge/demos/github-issue/demo-manual.md @@ -4,7 +4,7 @@ This guide walks through deploying the **GitHub Issue Agent** with **AuthBridge* using `kubectl` commands exclusively. All resources — agent, tool, ConfigMaps, and secrets — are deployed via Kubernetes manifests. -For a UI-driven deployment using the Kagenti dashboard, see [demo-ui.md](demo-ui.md). +For a UI-driven deployment using the Rossoctl dashboard, see [demo-ui.md](demo-ui.md). For a simpler getting-started demo, see the [Weather Agent demo](../weather-agent/demo-ui.md). ## What This Demo Shows @@ -75,7 +75,7 @@ providing end-to-end security: │ │ SPIRE (namespace: │ │ KEYCLOAK (namespace: │ │ │ │ spire) │ │ keycloak) │ │ │ │ │ │ │ │ -│ │ Provides SPIFFE │ │ - kagenti realm │ │ +│ │ Provides SPIFFE │ │ - rossoctl realm │ │ │ │ identities (SVIDs) │ │ - token exchange │ │ │ └──────────────────────┘ └──────────────────────┘ │ └──────────────────────────────────────────────────────────────────────────────────┘ @@ -171,12 +171,12 @@ Envoy — the agent application never sees them. This is tested in ## Prerequisites -Ensure you have completed the Kagenti platform setup as described in the -[Installation Guide](https://github.com/kagenti/kagenti/blob/main/docs/install.md). +Ensure you have completed the Rossoctl platform setup as described in the +[Installation Guide](https://github.com/rossoctl/rossoctl/blob/main/docs/install.md). You should also have: -- The [kagenti-extensions](https://github.com/kagenti/kagenti-extensions) repo cloned -- The [agent-examples](https://github.com/kagenti/agent-examples) repo cloned +- The [rossocortex](https://github.com/rossoctl/rossocortex) repo cloned +- The [agent-examples](https://github.com/rossoctl/examples) repo cloned - Python 3.9+ with `venv` support - **Ollama running** with the `ibm/granite4:latest` model (or another model of your choice) - Two GitHub Personal Access Tokens (PATs): @@ -198,7 +198,7 @@ see issues on public repositories. ### Build and Load Container Images + registry. Track: https://github.com/rossoctl/examples/issues — no issue filed yet. --> The agent and tool container images must be built locally and loaded into the kind cluster (they are not published to a public registry): @@ -207,23 +207,23 @@ cluster (they are not published to a public registry): cd /agent-examples # Build the GitHub tool image -docker build -t ghcr.io/kagenti/agent-examples/github-tool:latest \ +docker build -t ghcr.io/rossoctl/examples/github-tool:latest \ -f mcp/github_tool/Dockerfile mcp/github_tool/ # Build the GitHub Issue Agent image -docker build -t ghcr.io/kagenti/agent-examples/git-issue-agent:latest \ +docker build -t ghcr.io/rossoctl/examples/git-issue-agent:latest \ -f a2a/git_issue_agent/Dockerfile a2a/git_issue_agent/ # Load both images into the kind cluster -kind load docker-image --name kagenti ghcr.io/kagenti/agent-examples/github-tool:latest -kind load docker-image --name kagenti ghcr.io/kagenti/agent-examples/git-issue-agent:latest +kind load docker-image --name rossoctl ghcr.io/rossoctl/examples/github-tool:latest +kind load docker-image --name rossoctl ghcr.io/rossoctl/examples/git-issue-agent:latest ``` --- ## Step 1: Deploy the Operator Webhook with AuthBridge Support -The [kagenti-operator](https://github.com/kagenti/kagenti-operator) webhook automatically injects AuthBridge sidecars into agent deployments. See the operator docs for installation. +The [operator](https://github.com/rossoctl/operator) webhook automatically injects AuthBridge sidecars into agent deployments. See the operator docs for installation. Once the webhook is deployed, create the namespace and apply the ConfigMaps: @@ -276,7 +276,7 @@ This creates: | Resource | Name | Purpose | |----------|------|---------| -| **Realm** | `kagenti` | Keycloak realm for the demo | +| **Realm** | `rossoctl` | Keycloak realm for the demo | | **Client** | `github-tool` | Target audience for token exchange | | **Scope** | `agent-team1-git-issue-agent-aud` | Realm DEFAULT — auto-adds Agent's SPIFFE ID to all tokens | | **Scope** | `github-tool-aud` | Realm OPTIONAL — for exchanged tokens targeting the tool | @@ -288,9 +288,9 @@ This creates: ## Step 3: Apply Demo ConfigMaps -The Kagenti installer creates default ConfigMaps (`authbridge-config`, +The Rossoctl installer creates default ConfigMaps (`authbridge-config`, `spiffe-helper-config`, `envoy-config`) and the `keycloak-admin-secret` Secret -in the target namespace with the correct `kagenti` realm settings and 300s Envoy +in the target namespace with the correct `rossoctl` realm settings and 300s Envoy timeouts. No manual secret creation is needed for this demo. > If your Keycloak admin credentials differ from the default (`admin`/`admin`), @@ -411,20 +411,20 @@ github-tool-7f8c9d6b44-yyyyy 1/1 Running 0 3m ### Check operator-managed client registration -After kagenti-extensions#411 / kagenti-operator#361, registration runs in -the kagenti-operator (outside the workload pod). Verify the resulting +After rossocortex#411 / operator#361, registration runs in +the operator (outside the workload pod). Verify the resulting Secret was mounted into the agent's sidecar: ```bash kubectl get pod -n team1 -l app.kubernetes.io/name=git-issue-agent \ -o jsonpath='{.items[0].spec.volumes[?(@.secret)].secret.secretName}' -# Expect a Secret name starting with: kagenti-keycloak-client-credentials- +# Expect a Secret name starting with: rossoctl-keycloak-client-credentials- ``` Follow the operator-side registration: ```bash -kubectl logs -n kagenti-system deployment/kagenti-controller-manager \ +kubectl logs -n rossoctl-system deployment/rossoctl-controller-manager \ | grep -iE "clientregistration|git-issue-agent" | tail -20 ``` @@ -435,7 +435,7 @@ log format): ClientRegistrationReconciler: ensured Keycloak client spiffe://localtest.me/ns/team1/sa/git-issue-agent ClientRegistrationReconciler: wrote Secret - kagenti-keycloak-client-credentials- + rossoctl-keycloak-client-credentials- ``` ### Check agent logs @@ -457,7 +457,7 @@ INFO: Application startup complete. INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit) ``` - + > **These warnings are expected and harmless.** The agent's built-in auth code > probes for SVID and client-secret files at startup. With AuthBridge, these files @@ -467,7 +467,7 @@ INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit) > correct behavior — AuthBridge handles inbound JWT validation and outbound > token exchange on behalf of the agent. > These warnings will be removed once the agent's built-in auth logic is cleaned up -> ([kagenti/agent-examples#129](https://github.com/kagenti/agent-examples/issues/129)). +> ([rossoctl/examples#129](https://github.com/rossoctl/examples/issues/129)). ### Verify Ollama is running @@ -513,7 +513,7 @@ kubectl wait --for=condition=ready pod/test-client -n team1 --timeout=30s ### 8a. Agent Card - Public Endpoint (No Token Required) The `/.well-known/agent.json` endpoint is publicly accessible — authbridge -[bypasses JWT validation](https://github.com/kagenti/kagenti-extensions/pull/133) +[bypasses JWT validation](https://github.com/rossoctl/rossocortex/pull/133) for `/.well-known/*`, `/healthz`, `/readyz`, and `/livez` by default: ```bash @@ -550,7 +550,7 @@ A properly signed token from a **different Keycloak realm** has a valid signatur the issuer does not match the configured `ISSUER` in `authbridge-config`: ```bash -# Get a valid token from the master realm (different issuer than "kagenti") +# Get a valid token from the master realm (different issuer than "rossoctl") WRONG_ISSUER_TOKEN=$(kubectl exec test-client -n team1 -- curl -s \ "http://keycloak-service.keycloak.svc:8080/realms/master/protocol/openid-connect/token" \ -d "grant_type=password" \ @@ -561,7 +561,7 @@ WRONG_ISSUER_TOKEN=$(kubectl exec test-client -n team1 -- curl -s \ kubectl exec test-client -n team1 -- curl -s \ -H "Authorization: Bearer $WRONG_ISSUER_TOKEN" \ http://git-issue-agent:8080/ -# Expected: {"error":"unauthorized","message":"token validation failed: invalid issuer: expected http://keycloak.localtest.me:8080/realms/kagenti, got ..."} +# Expected: {"error":"unauthorized","message":"token validation failed: invalid issuer: expected http://keycloak.localtest.me:8080/realms/rossoctl, got ..."} ``` > **Why this matters:** Even though the token is cryptographically valid (signed by @@ -579,7 +579,7 @@ SIDECAR=$(kubectl get pod -n team1 -l app.kubernetes.io/name=git-issue-agent \ | grep -E '^(authbridge-proxy|envoy-proxy)$' | head -1) # Get the agent's client credentials (mounted by the operator-managed -# ClientRegistration controller via the kagenti-keycloak-client-credentials +# ClientRegistration controller via the rossoctl-keycloak-client-credentials # Secret, then mounted into the sidecar at /shared/). CLIENT_ID=$(kubectl exec deployment/git-issue-agent -n team1 -c "$SIDECAR" -- cat /shared/client-id.txt) CLIENT_SECRET=$(kubectl exec deployment/git-issue-agent -n team1 -c "$SIDECAR" -- cat /shared/client-secret.txt) @@ -587,7 +587,7 @@ echo "Agent Client ID: $CLIENT_ID" # Get a service account token (simulating what the UI would obtain) TOKEN=$(kubectl exec test-client -n team1 -- curl -s -X POST \ - "http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/token" \ + "http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/token" \ -d "grant_type=client_credentials" \ -d "client_id=$CLIENT_ID" \ -d "client_secret=$CLIENT_SECRET" | jq -r '.access_token') @@ -632,8 +632,8 @@ Expected (one line per request in 8b–8e): ``` [Inbound] Missing Authorization header [Inbound] JWT validation failed: failed to parse/validate token: ... -[Inbound] JWT validation failed: invalid issuer: expected http://keycloak.localtest.me:8080/realms/kagenti, got ... -[Inbound] Token validated - issuer: http://keycloak.localtest.me:8080/realms/kagenti, audience: [...] +[Inbound] JWT validation failed: invalid issuer: expected http://keycloak.localtest.me:8080/realms/rossoctl, got ... +[Inbound] Token validated - issuer: http://keycloak.localtest.me:8080/realms/rossoctl, audience: [...] [Inbound] JWT validation succeeded, forwarding request ``` @@ -667,8 +667,8 @@ kubectl exec -it test-client -n team1 -- sh Inside the test-client pod, run: ```bash -# Get a Keycloak admin token from the kagenti realm -ADMIN_TOKEN=$(curl -s http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/token \ +# Get a Keycloak admin token from the rossoctl realm +ADMIN_TOKEN=$(curl -s http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/token \ -d "grant_type=password" \ -d "client_id=admin-cli" \ -d "username=admin" \ @@ -678,11 +678,11 @@ echo "Admin token length: ${#ADMIN_TOKEN}" # Expected: Admin token length: 782 # If 0 or 4 (null), Keycloak is not reachable or credentials are wrong — stop here. -# Look up the agent's client in the kagenti realm. +# Look up the agent's client in the rossoctl realm. # The client ID is the SPIFFE ID (URL-encoded in the query parameter). SPIFFE_ID="spiffe://localtest.me/ns/team1/sa/git-issue-agent" CLIENTS=$(curl -s -H "Authorization: Bearer $ADMIN_TOKEN" \ - "http://keycloak-service.keycloak.svc:8080/admin/realms/kagenti/clients" \ + "http://keycloak-service.keycloak.svc:8080/admin/realms/rossoctl/clients" \ --data-urlencode "clientId=$SPIFFE_ID" --get) INTERNAL_ID=$(echo "$CLIENTS" | jq -r ".[0].id") CLIENT_ID=$(echo "$CLIENTS" | jq -r ".[0].clientId") @@ -699,7 +699,7 @@ echo "Secret length: ${#CLIENT_SECRET}" # Get an OAuth token for the agent TOKEN=$(curl -s -X POST \ - "http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/token" \ + "http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/token" \ -d "grant_type=client_credentials" \ --data-urlencode "client_id=$CLIENT_ID" \ --data-urlencode "client_secret=$CLIENT_SECRET" | jq -r ".access_token") @@ -720,7 +720,7 @@ Token length: 1165 > **Troubleshooting:** If `INTERNAL_ID` shows `null`, the Keycloak query didn't find > the client. Verify `$ADMIN_TOKEN` is not empty (Keycloak reachable?) and that > `setup_keycloak.py` was run. You can also list all clients with: -> `curl -s -H "Authorization: Bearer $ADMIN_TOKEN" "http://keycloak-service.keycloak.svc:8080/admin/realms/kagenti/clients" | jq '.[].clientId'` +> `curl -s -H "Authorization: Bearer $ADMIN_TOKEN" "http://keycloak-service.keycloak.svc:8080/admin/realms/rossoctl/clients" | jq '.[].clientId'` ### 9c. Send a prompt to the agent @@ -749,7 +749,7 @@ curl -s --max-time 300 \ "message": { "role": "user", "messageId": "msg-001", - "parts": [{"type": "text", "text": "List issues in kagenti/kagenti repo"}] + "parts": [{"type": "text", "text": "List issues in rossoctl/rossoctl repo"}] } } }' | jq @@ -807,7 +807,7 @@ kubectl logs deployment/git-issue-agent -n team1 -c "$SIDECAR" 2>&1 | grep -i "i Expected output: ``` -[Inbound] Token validated - issuer: http://keycloak.localtest.me:8080/realms/kagenti, audience: [spiffe://localtest.me/ns/team1/sa/git-issue-agent ...] +[Inbound] Token validated - issuer: http://keycloak.localtest.me:8080/realms/rossoctl, audience: [spiffe://localtest.me/ns/team1/sa/git-issue-agent ...] [Inbound] JWT validation succeeded, forwarding request ``` @@ -816,7 +816,7 @@ If you ran the rejection tests (8b, 8c, 8d), you should also see: ``` [Inbound] Missing Authorization header [Inbound] JWT validation failed: failed to parse/validate token: ... -[Inbound] JWT validation failed: invalid issuer: expected http://keycloak.localtest.me:8080/realms/kagenti, got ... +[Inbound] JWT validation failed: invalid issuer: expected http://keycloak.localtest.me:8080/realms/rossoctl, got ... ``` **Outbound token exchange logs** (RFC 8693 token exchange for the GitHub tool): @@ -828,7 +828,7 @@ kubectl logs deployment/git-issue-agent -n team1 -c "$SIDECAR" 2>&1 | grep "^202 Expected: ``` -[Token Exchange] Token URL: http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/token +[Token Exchange] Token URL: http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/token [Token Exchange] Client ID: spiffe://localtest.me/ns/team1/sa/git-issue-agent [Token Exchange] Audience: github-tool [Token Exchange] Scopes: openid github-tool-aud github-full-access @@ -846,14 +846,14 @@ kubectl delete pod test-client -n team1 --ignore-not-found ## Step 10: Access Control — Alice vs Bob - + Track: https://github.com/rossoctl/rossocortex/issues/139 --> > **Known limitation:** This step requires the authbridge scope forwarding feature -> ([kagenti-extensions#139](https://github.com/kagenti/kagenti-extensions/issues/139)). +> ([rossocortex#139](https://github.com/rossoctl/rossocortex/issues/139)). > Currently, `token_scopes` in the `authproxy-routes` ConfigMap is static per-route, so > all exchanged tokens include `github-full-access` regardless of the original user's > scopes. Once scope forwarding is implemented, Alice's exchanged token will omit @@ -873,7 +873,7 @@ The flow: (`github-full-access` is a realm OPTIONAL scope — Keycloak only includes it when the token request contains `scope=openid github-full-access`) 3. AuthBridge exchanges the token — once scope forwarding is implemented - ([#139](https://github.com/kagenti/kagenti-extensions/issues/139)), the exchanged + ([#139](https://github.com/rossoctl/rossocortex/issues/139)), the exchanged token will preserve the scope difference 4. The GitHub tool checks for `REQUIRED_SCOPE` (`github-full-access`) in the exchanged token 5. Tokens with the scope get the privileged PAT; tokens without get the public-only PAT @@ -896,7 +896,7 @@ Inside the test-client pod, get the agent's client credentials (needed to reques user tokens that include the agent's audience): ```bash -ADMIN_TOKEN=$(curl -s http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/token \ +ADMIN_TOKEN=$(curl -s http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/token \ -d "grant_type=password" \ -d "client_id=admin-cli" \ -d "username=admin" \ @@ -904,7 +904,7 @@ ADMIN_TOKEN=$(curl -s http://keycloak-service.keycloak.svc:8080/realms/kagenti/p SPIFFE_ID="spiffe://localtest.me/ns/team1/sa/git-issue-agent" CLIENTS=$(curl -s -H "Authorization: Bearer $ADMIN_TOKEN" \ - "http://keycloak-service.keycloak.svc:8080/admin/realms/kagenti/clients" \ + "http://keycloak-service.keycloak.svc:8080/admin/realms/rossoctl/clients" \ --data-urlencode "clientId=$SPIFFE_ID" --get) INTERNAL_ID=$(echo "$CLIENTS" | jq -r ".[0].id") CLIENT_ID=$(echo "$CLIENTS" | jq -r ".[0].clientId") @@ -919,7 +919,7 @@ Alice authenticates with Keycloak using `password` grant **without** requesting ```bash ALICE_TOKEN=$(curl -s -X POST \ - "http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/token" \ + "http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/token" \ -d "grant_type=password" \ -d "username=alice" \ -d "password=alice123" \ @@ -945,7 +945,7 @@ curl -s --max-time 300 \ "message": { "role": "user", "messageId": "msg-alice-1", - "parts": [{"type": "text", "text": "List issues in kagenti/kagenti repo"}] + "parts": [{"type": "text", "text": "List issues in rossoctl/rossoctl repo"}] } } }' | jq '.result.artifacts[0].parts[0].text' | head -5 @@ -982,7 +982,7 @@ the privileged scope: ```bash BOB_TOKEN=$(curl -s -X POST \ - "http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/token" \ + "http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/token" \ -d "grant_type=password" \ -d "username=bob" \ -d "password=bob123" \ @@ -1074,7 +1074,7 @@ kubectl get secret keycloak-admin-secret -n team1 # 2. Verify the authbridge-config ConfigMap has the correct realm kubectl get configmap authbridge-config -n team1 -o jsonpath='{.data.KEYCLOAK_REALM}' -# Should show: kagenti +# Should show: rossoctl # 3. Re-apply the demo ConfigMap and restart kubectl apply -f demos/github-issue/k8s/configmaps.yaml @@ -1117,7 +1117,7 @@ kubectl logs deployment/git-issue-agent -n team1 -c authbridge-proxy kubectl logs deployment/git-issue-agent -n team1 -c agent # Operator-managed registration: -kubectl logs -n kagenti-system deployment/kagenti-controller-manager \ +kubectl logs -n rossoctl-system deployment/rossoctl-controller-manager \ | grep -iE "clientregistration|git-issue-agent" | tail -20 ``` @@ -1126,7 +1126,7 @@ kubectl logs -n kagenti-system deployment/kagenti-controller-manager \ **Symptom:** Tool rejects the exchanged token **Fix:** Verify the tool's environment variables match the Keycloak configuration: -- `ISSUER` should be `http://keycloak.localtest.me:8080/realms/kagenti` +- `ISSUER` should be `http://keycloak.localtest.me:8080/realms/rossoctl` - `AUDIENCE` should be `github-tool` ### Upstream Request Timeout @@ -1143,7 +1143,7 @@ ConfigMap has the correct values: kubectl get configmap envoy-config -n team1 -o jsonpath='{.data.envoy\.yaml}' | grep "timeout:" ``` -If you see `30s` values instead of `300s`, reinstall Kagenti (the installer +If you see `30s` values instead of `300s`, reinstall Rossoctl (the installer creates the correct defaults) and restart the agent: ```bash @@ -1178,7 +1178,7 @@ kubectl delete namespace team1 ### Remove Webhook (optional) ```bash -kubectl delete mutatingwebhookconfiguration kagenti-webhook-authbridge-mutating-webhook-configuration +kubectl delete mutatingwebhookconfiguration rossoctl-webhook-authbridge-mutating-webhook-configuration ``` --- @@ -1196,7 +1196,7 @@ kubectl delete mutatingwebhookconfiguration kagenti-webhook-authbridge-mutating- ## Next Steps -- **UI Deployment**: See [demo-ui.md](demo-ui.md) for deploying via the Kagenti dashboard +- **UI Deployment**: See [demo-ui.md](demo-ui.md) for deploying via the Rossoctl dashboard - **AuthBridge Binary**: See the [AuthBridge README](../../cmd/authbridge/README.md) for inbound JWT validation and outbound token exchange internals - **Token-Exchange Routes**: See the [routes-configuration guide](../token-exchange-routes/README.md) for diff --git a/authbridge/demos/github-issue/demo-rbac.md b/authbridge/demos/github-issue/demo-rbac.md index bdc3f76e1..54a967d1d 100644 --- a/authbridge/demos/github-issue/demo-rbac.md +++ b/authbridge/demos/github-issue/demo-rbac.md @@ -4,7 +4,7 @@ This guide walks through deploying the **GitHub Issue Agent** with **AuthBridge* using `kubectl` commands exclusively. All resources — agent, tool, ConfigMaps, and secrets — are deployed via Kubernetes manifests. -For a UI-driven deployment using the Kagenti dashboard, see [demo-ui.md](demo-ui.md). +For a UI-driven deployment using the Rossoctl dashboard, see [demo-ui.md](demo-ui.md). For a simpler getting-started demo, see the [Weather Agent demo](../weather-agent/demo-ui.md). ## What This Demo Shows @@ -75,7 +75,7 @@ providing end-to-end security: │ │ SPIRE (namespace: │ │ KEYCLOAK (namespace: │ │ │ │ spire) │ │ keycloak) │ │ │ │ │ │ │ │ -│ │ Provides SPIFFE │ │ - kagenti realm │ │ +│ │ Provides SPIFFE │ │ - rossoctl realm │ │ │ │ identities (SVIDs) │ │ - token exchange │ │ │ └──────────────────────┘ └──────────────────────┘ │ └──────────────────────────────────────────────────────────────────────────────────┘ @@ -171,12 +171,12 @@ Envoy — the agent application never sees them. This is tested in ## Prerequisites -Ensure you have completed the Kagenti platform setup as described in the -[Installation Guide](https://github.com/kagenti/kagenti/blob/main/docs/install.md). +Ensure you have completed the Rossoctl platform setup as described in the +[Installation Guide](https://github.com/rossoctl/rossoctl/blob/main/docs/install.md). You should also have: -- The [kagenti-extensions](https://github.com/kagenti/kagenti-extensions) repo cloned -- The [agent-examples](https://github.com/kagenti/agent-examples) repo cloned +- The [rossocortex](https://github.com/rossoctl/rossocortex) repo cloned +- The [agent-examples](https://github.com/rossoctl/examples) repo cloned - Python 3.9+ with `venv` support - **Ollama running** with the `ibm/granite4:latest` model (or another model of your choice) - Two GitHub Personal Access Tokens (PATs): @@ -198,7 +198,7 @@ see issues on public repositories. ### Build and Load Container Images + registry. Track: https://github.com/rossoctl/examples/issues — no issue filed yet. --> The agent and tool container images must be built locally and loaded into the kind cluster (they are not published to a public registry): @@ -207,23 +207,23 @@ cluster (they are not published to a public registry): cd /agent-examples # Build the GitHub tool image -docker build -t ghcr.io/kagenti/agent-examples/github-tool:latest \ +docker build -t ghcr.io/rossoctl/examples/github-tool:latest \ -f mcp/github_tool/Dockerfile mcp/github_tool/ # Build the GitHub Issue Agent image -docker build -t ghcr.io/kagenti/agent-examples/git-issue-agent:latest \ +docker build -t ghcr.io/rossoctl/examples/git-issue-agent:latest \ -f a2a/git_issue_agent/Dockerfile a2a/git_issue_agent/ # Load both images into the kind cluster -kind load docker-image --name kagenti ghcr.io/kagenti/agent-examples/github-tool:latest -kind load docker-image --name kagenti ghcr.io/kagenti/agent-examples/git-issue-agent:latest +kind load docker-image --name rossoctl ghcr.io/rossoctl/examples/github-tool:latest +kind load docker-image --name rossoctl ghcr.io/rossoctl/examples/git-issue-agent:latest ``` --- ## Step 1: Deploy the Operator Webhook with AuthBridge Support -The [kagenti-operator](https://github.com/kagenti/kagenti-operator) webhook automatically injects AuthBridge sidecars into agent deployments. See the operator docs for installation. +The [operator](https://github.com/rossoctl/operator) webhook automatically injects AuthBridge sidecars into agent deployments. See the operator docs for installation. Once the webhook is deployed, create the namespace and apply the ConfigMaps: @@ -272,7 +272,7 @@ This creates: | Resource | Name | Purpose | |----------|------|---------| -| **Realm** | `kagenti` | Keycloak realm for the demo | +| **Realm** | `rossoctl` | Keycloak realm for the demo | | **Client** | `spiffe://localtest.me/ns/team1/sa/git-issue-agent` | Agent client (already existed) with github-agent role | | **Client** | `github-tool` | Target audience for token exchange | | **Client Role** | `github-agent` | Access role for the GitHub issue agent | @@ -288,9 +288,9 @@ This creates: ## Step 3: Apply Demo ConfigMaps -The Kagenti installer creates default ConfigMaps (`authbridge-config`, +The Rossoctl installer creates default ConfigMaps (`authbridge-config`, `spiffe-helper-config`, `envoy-config`) and the `keycloak-admin-secret` Secret -in the target namespace with the correct `kagenti` realm settings and 300s Envoy +in the target namespace with the correct `rossoctl` realm settings and 300s Envoy timeouts. No manual secret creation is needed for this demo. > If your Keycloak admin credentials differ from the default (`admin`/`admin`), @@ -411,20 +411,20 @@ github-tool-7f8c9d6b44-yyyyy 1/1 Running 0 3m ### Check operator-managed client registration -After kagenti-extensions#411 / kagenti-operator#361, registration runs in -the kagenti-operator (outside the workload pod). Verify the resulting +After rossocortex#411 / operator#361, registration runs in +the operator (outside the workload pod). Verify the resulting Secret was mounted into the agent's sidecar: ```bash kubectl get pod -n team1 -l app.kubernetes.io/name=git-issue-agent \ -o jsonpath='{.items[0].spec.volumes[?(@.secret)].secret.secretName}' -# Expect a Secret name starting with: kagenti-keycloak-client-credentials- +# Expect a Secret name starting with: rossoctl-keycloak-client-credentials- ``` Follow the operator-side registration: ```bash -kubectl logs -n kagenti-system deployment/kagenti-controller-manager \ +kubectl logs -n rossoctl-system deployment/rossoctl-controller-manager \ | grep -iE "clientregistration|git-issue-agent" | tail -20 ``` @@ -435,7 +435,7 @@ log format): ClientRegistrationReconciler: ensured Keycloak client spiffe://localtest.me/ns/team1/sa/git-issue-agent ClientRegistrationReconciler: wrote Secret - kagenti-keycloak-client-credentials- + rossoctl-keycloak-client-credentials- ``` ### Check agent logs @@ -457,7 +457,7 @@ INFO: Application startup complete. INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit) ``` - + > **These warnings are expected and harmless.** The agent's built-in auth code > probes for SVID and client-secret files at startup. With AuthBridge, these files @@ -467,7 +467,7 @@ INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit) > correct behavior — AuthBridge handles inbound JWT validation and outbound > token exchange on behalf of the agent. > These warnings will be removed once the agent's built-in auth logic is cleaned up -> ([kagenti/agent-examples#129](https://github.com/kagenti/agent-examples/issues/129)). +> ([rossoctl/examples#129](https://github.com/rossoctl/examples/issues/129)). ### Verify Ollama is running @@ -513,7 +513,7 @@ kubectl wait --for=condition=ready pod/test-client -n team1 --timeout=30s ### 8a. Agent Card - Public Endpoint (No Token Required) The `/.well-known/agent.json` endpoint is publicly accessible — authbridge -[bypasses JWT validation](https://github.com/kagenti/kagenti-extensions/pull/133) +[bypasses JWT validation](https://github.com/rossoctl/rossocortex/pull/133) for `/.well-known/*`, `/healthz`, `/readyz`, and `/livez` by default: ```bash @@ -550,7 +550,7 @@ A properly signed token from a **different Keycloak realm** has a valid signatur the issuer does not match the configured `ISSUER` in `authbridge-config`: ```bash -# Get a valid token from the master realm (different issuer than "kagenti") +# Get a valid token from the master realm (different issuer than "rossoctl") WRONG_ISSUER_TOKEN=$(kubectl exec test-client -n team1 -- curl -s \ "http://keycloak-service.keycloak.svc:8080/realms/master/protocol/openid-connect/token" \ -d "grant_type=password" \ @@ -561,7 +561,7 @@ WRONG_ISSUER_TOKEN=$(kubectl exec test-client -n team1 -- curl -s \ kubectl exec test-client -n team1 -- curl -s \ -H "Authorization: Bearer $WRONG_ISSUER_TOKEN" \ http://git-issue-agent:8080/ -# Expected: {"error":"unauthorized","message":"token validation failed: invalid issuer: expected http://keycloak.localtest.me:8080/realms/kagenti, got ..."} +# Expected: {"error":"unauthorized","message":"token validation failed: invalid issuer: expected http://keycloak.localtest.me:8080/realms/rossoctl, got ..."} ``` > **Why this matters:** Even though the token is cryptographically valid (signed by @@ -579,7 +579,7 @@ SIDECAR=$(kubectl get pod -n team1 -l app.kubernetes.io/name=git-issue-agent \ | grep -E '^(authbridge-proxy|envoy-proxy)$' | head -1) # Get the agent's client credentials (mounted by the operator-managed -# ClientRegistration controller via the kagenti-keycloak-client-credentials +# ClientRegistration controller via the rossoctl-keycloak-client-credentials # Secret, then mounted into the sidecar at /shared/). CLIENT_ID=$(kubectl exec deployment/git-issue-agent -n team1 -c "$SIDECAR" -- cat /shared/client-id.txt) CLIENT_SECRET=$(kubectl exec deployment/git-issue-agent -n team1 -c "$SIDECAR" -- cat /shared/client-secret.txt) @@ -587,7 +587,7 @@ echo "Agent Client ID: $CLIENT_ID" # Get a service account token (simulating what the UI would obtain) TOKEN=$(kubectl exec test-client -n team1 -- curl -s -X POST \ - "http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/token" \ + "http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/token" \ -d "grant_type=client_credentials" \ -d "client_id=$CLIENT_ID" \ -d "client_secret=$CLIENT_SECRET" | jq -r '.access_token') @@ -632,8 +632,8 @@ Expected (one line per request in 8b–8e): ``` [Inbound] Missing Authorization header [Inbound] JWT validation failed: failed to parse/validate token: ... -[Inbound] JWT validation failed: invalid issuer: expected http://keycloak.localtest.me:8080/realms/kagenti, got ... -[Inbound] Token validated - issuer: http://keycloak.localtest.me:8080/realms/kagenti, audience: [...] +[Inbound] JWT validation failed: invalid issuer: expected http://keycloak.localtest.me:8080/realms/rossoctl, got ... +[Inbound] Token validated - issuer: http://keycloak.localtest.me:8080/realms/rossoctl, audience: [...] [Inbound] JWT validation succeeded, forwarding request ``` @@ -667,8 +667,8 @@ kubectl exec -it test-client -n team1 -- sh Inside the test-client pod, run: ```bash -# Get a Keycloak admin token from the kagenti realm -ADMIN_TOKEN=$(curl -s http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/token \ +# Get a Keycloak admin token from the rossoctl realm +ADMIN_TOKEN=$(curl -s http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/token \ -d "grant_type=password" \ -d "client_id=admin-cli" \ -d "username=admin" \ @@ -678,11 +678,11 @@ echo "Admin token length: ${#ADMIN_TOKEN}" # Expected: Admin token length: 782 # If 0 or 4 (null), Keycloak is not reachable or credentials are wrong — stop here. -# Look up the agent's client in the kagenti realm. +# Look up the agent's client in the rossoctl realm. # The client ID is the SPIFFE ID (URL-encoded in the query parameter). SPIFFE_ID="spiffe://localtest.me/ns/team1/sa/git-issue-agent" CLIENTS=$(curl -s -H "Authorization: Bearer $ADMIN_TOKEN" \ - "http://keycloak-service.keycloak.svc:8080/admin/realms/kagenti/clients" \ + "http://keycloak-service.keycloak.svc:8080/admin/realms/rossoctl/clients" \ --data-urlencode "clientId=$SPIFFE_ID" --get) INTERNAL_ID=$(echo "$CLIENTS" | jq -r ".[0].id") CLIENT_ID=$(echo "$CLIENTS" | jq -r ".[0].clientId") @@ -699,7 +699,7 @@ echo "Secret length: ${#CLIENT_SECRET}" # Get an OAuth token for the agent TOKEN=$(curl -s -X POST \ - "http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/token" \ + "http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/token" \ -d "grant_type=client_credentials" \ --data-urlencode "client_id=$CLIENT_ID" \ --data-urlencode "client_secret=$CLIENT_SECRET" | jq -r ".access_token") @@ -720,7 +720,7 @@ Token length: 1165 > **Troubleshooting:** If `INTERNAL_ID` shows `null`, the Keycloak query didn't find > the client. Verify `$ADMIN_TOKEN` is not empty (Keycloak reachable?) and that > `setup_keycloak.py` was run. You can also list all clients with: -> `curl -s -H "Authorization: Bearer $ADMIN_TOKEN" "http://keycloak-service.keycloak.svc:8080/admin/realms/kagenti/clients" | jq '.[].clientId'` +> `curl -s -H "Authorization: Bearer $ADMIN_TOKEN" "http://keycloak-service.keycloak.svc:8080/admin/realms/rossoctl/clients" | jq '.[].clientId'` ### 9c. Send a prompt to the agent @@ -749,7 +749,7 @@ curl -s --max-time 300 \ "message": { "role": "user", "messageId": "msg-001", - "parts": [{"type": "text", "text": "List issues in kagenti/kagenti repo"}] + "parts": [{"type": "text", "text": "List issues in rossoctl/rossoctl repo"}] } } }' | jq @@ -807,7 +807,7 @@ kubectl logs deployment/git-issue-agent -n team1 -c "$SIDECAR" 2>&1 | grep -i "i Expected output: ``` -[Inbound] Token validated - issuer: http://keycloak.localtest.me:8080/realms/kagenti, audience: [spiffe://localtest.me/ns/team1/sa/git-issue-agent ...] +[Inbound] Token validated - issuer: http://keycloak.localtest.me:8080/realms/rossoctl, audience: [spiffe://localtest.me/ns/team1/sa/git-issue-agent ...] [Inbound] JWT validation succeeded, forwarding request ``` @@ -816,7 +816,7 @@ If you ran the rejection tests (8b, 8c, 8d), you should also see: ``` [Inbound] Missing Authorization header [Inbound] JWT validation failed: failed to parse/validate token: ... -[Inbound] JWT validation failed: invalid issuer: expected http://keycloak.localtest.me:8080/realms/kagenti, got ... +[Inbound] JWT validation failed: invalid issuer: expected http://keycloak.localtest.me:8080/realms/rossoctl, got ... ``` **Outbound token exchange logs** (RFC 8693 token exchange for the GitHub tool): @@ -828,7 +828,7 @@ kubectl logs deployment/git-issue-agent -n team1 -c "$SIDECAR" 2>&1 | grep "^202 Expected: ``` -[Token Exchange] Token URL: http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/token +[Token Exchange] Token URL: http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/token [Token Exchange] Client ID: spiffe://localtest.me/ns/team1/sa/git-issue-agent [Token Exchange] Audience: github-tool [Token Exchange] Scopes: openid github-tool-aud github-full-access @@ -879,7 +879,7 @@ Inside the test-client pod, get the agent's client credentials (needed to reques user tokens that include the agent's audience): ```bash -ADMIN_TOKEN=$(curl -s http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/token \ +ADMIN_TOKEN=$(curl -s http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/token \ -d "grant_type=password" \ -d "client_id=admin-cli" \ -d "username=admin" \ @@ -887,7 +887,7 @@ ADMIN_TOKEN=$(curl -s http://keycloak-service.keycloak.svc:8080/realms/kagenti/p SPIFFE_ID="spiffe://localtest.me/ns/team1/sa/git-issue-agent" CLIENTS=$(curl -s -H "Authorization: Bearer $ADMIN_TOKEN" \ - "http://keycloak-service.keycloak.svc:8080/admin/realms/kagenti/clients" \ + "http://keycloak-service.keycloak.svc:8080/admin/realms/rossoctl/clients" \ --data-urlencode "clientId=$SPIFFE_ID" --get) INTERNAL_ID=$(echo "$CLIENTS" | jq -r ".[0].id") CLIENT_ID=$(echo "$CLIENTS" | jq -r ".[0].clientId") @@ -901,7 +901,7 @@ Alice authenticates with Keycloak using `password` grant. ```bash ALICE_TOKEN=$(curl -s -X POST \ - "http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/token" \ + "http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/token" \ -d "grant_type=password" \ -d "username=alice" \ -d "password=alice123" \ @@ -927,7 +927,7 @@ curl -s --max-time 300 \ "message": { "role": "user", "messageId": "msg-alice-1", - "parts": [{"type": "text", "text": "List issues in kagenti/kagenti repo"}] + "parts": [{"type": "text", "text": "List issues in rossoctl/rossoctl repo"}] } } }' | jq '.result.artifacts[0].parts[0].text' | head -5 @@ -963,7 +963,7 @@ Bob authenticates with Keycloak using `password` grant. ```bash BOB_TOKEN=$(curl -s -X POST \ - "http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/token" \ + "http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/token" \ -d "grant_type=password" \ -d "username=bob" \ -d "password=bob123" \ @@ -1051,7 +1051,7 @@ kubectl get secret keycloak-admin-secret -n team1 # 2. Verify the authbridge-config ConfigMap has the correct realm kubectl get configmap authbridge-config -n team1 -o jsonpath='{.data.KEYCLOAK_REALM}' -# Should show: kagenti +# Should show: rossoctl # 3. Re-apply the demo ConfigMap and restart kubectl apply -f demos/github-issue/k8s/configmaps.yaml @@ -1094,7 +1094,7 @@ kubectl logs deployment/git-issue-agent -n team1 -c authbridge-proxy kubectl logs deployment/git-issue-agent -n team1 -c agent # Operator-managed registration: -kubectl logs -n kagenti-system deployment/kagenti-controller-manager \ +kubectl logs -n rossoctl-system deployment/rossoctl-controller-manager \ | grep -iE "clientregistration|git-issue-agent" | tail -20 ``` @@ -1103,7 +1103,7 @@ kubectl logs -n kagenti-system deployment/kagenti-controller-manager \ **Symptom:** Tool rejects the exchanged token **Fix:** Verify the tool's environment variables match the Keycloak configuration: -- `ISSUER` should be `http://keycloak.localtest.me:8080/realms/kagenti` +- `ISSUER` should be `http://keycloak.localtest.me:8080/realms/rossoctl` - `AUDIENCE` should be `github-tool` ### Upstream Request Timeout @@ -1120,7 +1120,7 @@ ConfigMap has the correct values: kubectl get configmap envoy-config -n team1 -o jsonpath='{.data.envoy\.yaml}' | grep "timeout:" ``` -If you see `30s` values instead of `300s`, reinstall Kagenti (the installer +If you see `30s` values instead of `300s`, reinstall Rossoctl (the installer creates the correct defaults) and restart the agent: ```bash @@ -1155,7 +1155,7 @@ kubectl delete namespace team1 ### Remove Webhook (optional) ```bash -kubectl delete mutatingwebhookconfiguration kagenti-webhook-authbridge-mutating-webhook-configuration +kubectl delete mutatingwebhookconfiguration rossoctl-webhook-authbridge-mutating-webhook-configuration ``` --- diff --git a/authbridge/demos/github-issue/demo-ui.md b/authbridge/demos/github-issue/demo-ui.md index 67931380d..87cd0cb1e 100644 --- a/authbridge/demos/github-issue/demo-ui.md +++ b/authbridge/demos/github-issue/demo-ui.md @@ -1,9 +1,9 @@ # GitHub Issue Agent Demo with AuthBridge (UI Deployment) This guide walks through deploying the **GitHub Issue Agent** with **AuthBridge** -using the **Kagenti UI** for agent and tool deployment. Infrastructure setup +using the **Rossoctl UI** for agent and tool deployment. Infrastructure setup (webhook, Keycloak, ConfigMaps) is done via CLI, while the agent and tool are -imported and deployed through the Kagenti dashboard. +imported and deployed through the Rossoctl dashboard. For a fully manual deployment using only `kubectl`, see [demo-manual.md](demo-manual.md). @@ -78,7 +78,7 @@ providing end-to-end security: │ │ SPIRE (namespace: │ │ KEYCLOAK (namespace: │ │ │ │ spire) │ │ keycloak) │ │ │ │ │ │ │ │ -│ │ Provides SPIFFE │ │ - kagenti realm │ │ +│ │ Provides SPIFFE │ │ - rossoctl realm │ │ │ │ identities (SVIDs) │ │ - token exchange │ │ │ └──────────────────────┘ └──────────────────────┘ │ └──────────────────────────────────────────────────────────────────────────────────┘ @@ -86,17 +86,17 @@ providing end-to-end security: ## Prerequisites -Ensure you have completed the Kagenti platform setup as described in the -[Installation Guide](https://github.com/kagenti/kagenti/blob/main/docs/install.md), -including the Kagenti UI. +Ensure you have completed the Rossoctl platform setup as described in the +[Installation Guide](https://github.com/rossoctl/rossoctl/blob/main/docs/install.md), +including the Rossoctl UI. You should also have: -- The [kagenti-extensions](https://github.com/kagenti/kagenti-extensions) repo cloned -- The Kagenti UI running at `http://kagenti-ui.localtest.me:8080` +- The [rossocortex](https://github.com/rossoctl/rossocortex) repo cloned +- The Rossoctl UI running at `http://rossoctl-ui.localtest.me:8080` - Python 3.10+ with `venv` support - An LLM provider — either **Ollama** with `ibm/granite4:latest` (or another model) or an **OpenAI API key** (recommended for reliable function calling; - see [agent-examples#173](https://github.com/kagenti/agent-examples/issues/173)) + see [agent-examples#173](https://github.com/rossoctl/examples/issues/173)) - Two GitHub Personal Access Tokens (PATs): - `` — access to public repositories only - `` — access to all repositories @@ -113,22 +113,22 @@ This lets you demonstrate finer-grained authorization: a user with full access can see issues on all repositories, while a user with partial access can only see issues on public repositories. -### Kagenti version notes (UI import and AuthBridge) +### Rossoctl version notes (UI import and AuthBridge) - **Outbound routes from the UI (Step 5, item 12):** The API must write `authproxy-routes` `routes.yaml` as a **YAML list** of route objects (same shape as - [k8s/configmaps.yaml](k8s/configmaps.yaml)). Older Kagenti backends wrapped routes in a + [k8s/configmaps.yaml](k8s/configmaps.yaml)). Older Rossoctl backends wrapped routes in a top-level `routes:` **map**, which **authbridge cannot parse**, so ext_proc never starts, Envoy returns **500** through the Service, and the UI shows **Agent card not - available**. Use a build that includes [kagenti/kagenti#1194](https://github.com/kagenti/kagenti/pull/1194) - ([#1195](https://github.com/kagenti/kagenti/issues/1195)), or use **Step 2 Option B** + available**. Use a build that includes [rossoctl/rossoctl#1194](https://github.com/rossoctl/rossoctl/pull/1194) + ([#1195](https://github.com/rossoctl/rossoctl/issues/1195)), or use **Step 2 Option B** (`kubectl apply -f demos/github-issue/k8s/configmaps.yaml`) and skip adding duplicate routes in the UI. - **Finalize after Shipwright:** If the build succeeds but the agent **Deployment never appears** and backend logs show **403** on ConfigMaps, upgrade the Helm chart to a - release that includes [kagenti/kagenti#1192](https://github.com/kagenti/kagenti/pull/1192) - ([#1191](https://github.com/kagenti/kagenti/issues/1191)). + release that includes [rossoctl/rossoctl#1192](https://github.com/rossoctl/rossoctl/pull/1192) + ([#1191](https://github.com/rossoctl/rossoctl/issues/1191)). --- @@ -166,7 +166,7 @@ This creates: | Resource | Name | Purpose | |----------|------|---------| -| **Realm** | `kagenti` | Keycloak realm for the demo | +| **Realm** | `rossoctl` | Keycloak realm for the demo | | **Client** | `github-tool` | Target audience for token exchange | | **Scope** | `agent-team1-git-issue-agent-aud` | Realm DEFAULT — auto-adds Agent's SPIFFE ID to all tokens | | **Scope** | `github-tool-aud` | Realm OPTIONAL — for exchanged tokens targeting the tool | @@ -178,9 +178,9 @@ This creates: ## Step 2: Apply Demo ConfigMaps -The Kagenti installer creates default ConfigMaps (`authbridge-config`, +The Rossoctl installer creates default ConfigMaps (`authbridge-config`, `spiffe-helper-config`, `envoy-config`) and the `keycloak-admin-secret` Secret -in the target namespace with the correct `kagenti` realm settings and 300s Envoy +in the target namespace with the correct `rossoctl` realm settings and 300s Envoy timeouts. No manual secret creation is needed for this demo. > If your Keycloak admin credentials differ from the default (`admin`/`admin`), @@ -195,10 +195,10 @@ timeouts. No manual secret creation is needed for this demo. The `authproxy-routes` ConfigMap (outbound routing rules for token exchange) can be configured in two ways: -**Option A (recommended): Via the Kagenti UI** — configure outbound routing +**Option A (recommended): Via the Rossoctl UI** — configure outbound routing rules directly during agent import in Step 5 (item 12). No manual ConfigMap -creation needed. Requires a Kagenti backend that writes list-shaped `routes.yaml` -(see [Kagenti version notes](#kagenti-version-notes-ui-import-and-authbridge) above); +creation needed. Requires a Rossoctl backend that writes list-shaped `routes.yaml` +(see [Rossoctl version notes](#rossoctl-version-notes-ui-import-and-authbridge) above); otherwise use Option B or upgrade. **Option B: Via kubectl** — apply the demo-specific ConfigMap that configures @@ -234,17 +234,17 @@ kubectl create secret generic github-tool-secrets -n team1 \ --- -## Step 4: Import the GitHub Tool via Kagenti UI +## Step 4: Import the GitHub Tool via Rossoctl UI -1. Navigate to [Import Tool](http://kagenti-ui.localtest.me:8080/tools/import) - in the Kagenti UI. +1. Navigate to [Import Tool](http://rossoctl-ui.localtest.me:8080/tools/import) + in the Rossoctl UI. 2. In the **Namespace** drop-down, choose `team1`. 3. Select **Build from Source** as the deployment method. 4. Under **Source Code** select: - - **Git Repository URL**: `https://github.com/kagenti/agent-examples` + - **Git Repository URL**: `https://github.com/rossoctl/examples` - **Git Branch or Tag**: `main` - **Select Tool**: `GitHub Tool` - **Source Subfolder**: `mcp/github_tool` @@ -270,7 +270,7 @@ kubectl create secret generic github-tool-secrets -n team1 \ 10. Under **Environment Variables**, click **Import from File/URL**, Select **From URL** and provide the `.env` file from this repo: - - **URL** `https://raw.githubusercontent.com/kagenti/agent-examples/refs/heads/main/mcp/github_tool/.env.authbridge` + - **URL** `https://raw.githubusercontent.com/rossoctl/examples/refs/heads/main/mcp/github_tool/.env.authbridge` - Click **Fetch & Parse** — this populates all environment variables, including Secret references for the PAT tokens and direct values for Keycloak settings. - Click **Import** to set all the env. variables. @@ -303,17 +303,17 @@ Expected: --- -## Step 5: Import the GitHub Issue Agent via Kagenti UI +## Step 5: Import the GitHub Issue Agent via Rossoctl UI -1. Navigate to [Import Agent](http://kagenti-ui.localtest.me:8080/agents/import) - in the Kagenti UI. +1. Navigate to [Import Agent](http://rossoctl-ui.localtest.me:8080/agents/import) + in the Rossoctl UI. 2. In the **Namespace** drop-down, choose `team1`. 3. Select **Build from Source** as the deployment method. 4. Under **Source Repository** select: - - **Git Repository URL**: `https://github.com/kagenti/agent-examples` + - **Git Repository URL**: `https://github.com/rossoctl/examples` - **Git Branch or Tag**: `main` - **Select Agent**: `Git Issue Agent` - **Source Subfolder**: `a2a/git_issue_agent` @@ -334,8 +334,8 @@ Expected: 11. Under **Environment Variables**, click **Import from File/URL**, Select **From URL** and provide the **URL** from this repo: - - For Ollama: `https://raw.githubusercontent.com/kagenti/agent-examples/refs/heads/main/a2a/git_issue_agent/.env.ollama` - - For OpenAI: `https://raw.githubusercontent.com/kagenti/agent-examples/refs/heads/main/a2a/git_issue_agent/.env.openai` + - For Ollama: `https://raw.githubusercontent.com/rossoctl/examples/refs/heads/main/a2a/git_issue_agent/.env.ollama` + - For OpenAI: `https://raw.githubusercontent.com/rossoctl/examples/refs/heads/main/a2a/git_issue_agent/.env.openai` - Click **Fetch & Parse** — this populates all environment variables including LLM settings, `MCP_URL`, and `JWKS_URI`. No manual editing is needed. - Click **Import** to set all the env. variables. @@ -365,7 +365,7 @@ Expected: > you can skip this — the UI-created routes will merge with existing ones. > **Troubleshooting:** If **Outbound Routing Rules** is missing, stays collapsed, - > or does not respond when you click it, your Kagenti UI build may not include this + > or does not respond when you click it, your Rossoctl UI build may not include this > control yet. Use **Step 2, Option B** instead: > `kubectl apply -f demos/github-issue/k8s/configmaps.yaml` from the `authbridge` > directory (same host, audience, and scopes as the table above). Then continue @@ -389,7 +389,7 @@ Wait for the Shipwright build to complete and the deployment to become ready. kubectl get pods -n team1 ``` -Expected output (after kagenti-extensions#411 / kagenti-operator#361: +Expected output (after rossocortex#411 / operator#361: one combined AuthBridge sidecar, registration is operator-managed): ``` @@ -425,20 +425,20 @@ agent envoy-proxy ### Check operator-managed client registration -After kagenti-operator#361 client registration runs in the operator +After operator#361 client registration runs in the operator (outside the workload pod). Verify the resulting Secret is mounted into the agent's sidecar: ```bash kubectl get pod -n team1 -l app.kubernetes.io/name=git-issue-agent \ -o jsonpath='{.items[0].spec.volumes[?(@.secret)].secret.secretName}' -# Expect a Secret name starting with: kagenti-keycloak-client-credentials- +# Expect a Secret name starting with: rossoctl-keycloak-client-credentials- ``` Follow the operator-side reconciler: ```bash -kubectl logs -n kagenti-system deployment/kagenti-controller-manager \ +kubectl logs -n rossoctl-system deployment/rossoctl-controller-manager \ | grep -iE "clientregistration|git-issue-agent" | tail -20 ``` @@ -449,7 +449,7 @@ log format): ClientRegistrationReconciler: ensured Keycloak client spiffe://localtest.me/ns/team1/sa/git-issue-agent ClientRegistrationReconciler: wrote Secret - kagenti-keycloak-client-credentials- + rossoctl-keycloak-client-credentials- ``` ### Check agent logs @@ -471,7 +471,7 @@ INFO: Application startup complete. INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit) ``` - + > **These warnings are expected and harmless.** The agent's built-in auth code > probes for SVID and client-secret files at startup. With AuthBridge, these files @@ -481,7 +481,7 @@ INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit) > correct behavior — AuthBridge handles inbound JWT validation and outbound > token exchange on behalf of the agent. > These warnings will be removed once the agent's built-in auth logic is cleaned up -> ([kagenti/agent-examples#129](https://github.com/kagenti/agent-examples/issues/129)). +> ([rossoctl/examples#129](https://github.com/rossoctl/examples/issues/129)). ### Check the service endpoint @@ -507,7 +507,7 @@ provider. > **Recommendation:** OpenAI (`gpt-4o-mini` or similar) is recommended for the most > reliable function-calling experience. Local Ollama models may produce text-based > tool outputs instead of structured function calls with `crewai 1.10.1` -> ([kagenti/agent-examples#173](https://github.com/kagenti/agent-examples/issues/173)). +> ([rossoctl/examples#173](https://github.com/rossoctl/examples/issues/173)). ### Option A: Ollama (local models) @@ -542,14 +542,14 @@ Otherwise, add the annotation after deployment: ```bash kubectl patch deployment git-issue-agent -n team1 --type=merge -p=' -{"spec":{"template":{"metadata":{"annotations":{"kagenti.io/outbound-ports-exclude":"11434"}}}}}' +{"spec":{"template":{"metadata":{"annotations":{"rossoctl.io/outbound-ports-exclude":"11434"}}}}}' kubectl rollout status deployment/git-issue-agent -n team1 --timeout=120s ``` ### Option B: OpenAI Verify the OpenAI secret exists (see the prerequisite note in -[Step 5](#step-5-import-the-github-issue-agent-via-kagenti-ui)): +[Step 5](#step-5-import-the-github-issue-agent-via-rossoctl-ui)): ```bash kubectl get secret openai-secret -n team1 @@ -575,28 +575,28 @@ OPENAI_API_KEY=sk-... --- -## Step 8: Chat via Kagenti UI +## Step 8: Chat via Rossoctl UI -1. Navigate to the **Agent Catalog** in the Kagenti UI. +1. Navigate to the **Agent Catalog** in the Rossoctl UI. 2. Select the `team1` namespace. 3. Under **Available Agents**, select `git-issue-agent` and click **View Details**. 4. Verify the **Agent Card** is visible (this confirms the agent is running and the `/.well-known/*` bypass is working). -5. Use the **Chat** panel to send a message, e.g. "List 10 open issues in kagenti/kagenti repo". +5. Use the **Chat** panel to send a message, e.g. "List 10 open issues in rossoctl/rossoctl repo". 6. The agent should respond with a list of GitHub issues. > **Intermittent short responses:** Sometimes the model returns only a CrewAI-style > planning line (e.g. `Thought: … Action: list_issues Action Input: …`) and stops > **before** the GitHub MCP tool runs, so you do not get a real issue list. This is -> **not** Kagenti UI caching or streaming truncation—the same text can appear from +> **not** Rossoctl UI caching or streaming truncation—the same text can appear from > `message/send` in [Step 9d](#9d-end-to-end-test-with-valid-token). **Workaround for > the demo:** send the same prompt again (in the UI or via `curl`) a few times until > you see a full answer. OpenAI models usually behave more consistently than local -> Ollama for tool use; see [agent-examples#173](https://github.com/kagenti/agent-examples/issues/173). +> Ollama for tool use; see [agent-examples#173](https://github.com/rossoctl/examples/issues/173). > Deeper diagnosis: [Partial response (Thought and Action only)](#partial-response-thought-and-action-only-no-issue-list). > **Troubleshooting:** If UI chat returns a `401`, verify that both the UI and -> AuthBridge are configured against the same `kagenti` realm. You can also use +> AuthBridge are configured against the same `rossoctl` realm. You can also use > [Step 9: Test via CLI](#step-9-test-via-cli) to test the full AuthBridge flow > independently. @@ -605,7 +605,7 @@ OPENAI_API_KEY=sk-... ## Step 9: Test via CLI Test the AuthBridge flow from the command line to verify inbound validation and -token exchange using a `kagenti`-realm token. +token exchange using a `rossoctl`-realm token. ### Setup @@ -618,7 +618,7 @@ kubectl wait --for=condition=ready pod/test-client -n team1 --timeout=30s ### 9a. Agent Card - Public Endpoint (No Token Required) The `/.well-known/agent.json` endpoint is publicly accessible — authbridge -[bypasses JWT validation](https://github.com/kagenti/kagenti-extensions/pull/133) +[bypasses JWT validation](https://github.com/rossoctl/rossocortex/pull/133) for `/.well-known/*`, `/healthz`, `/readyz`, and `/livez` by default: ```bash @@ -674,8 +674,8 @@ kubectl exec -it test-client -n team1 -- sh Inside the pod, get credentials and send a request: ```bash -# Get a Keycloak admin token from the kagenti realm -ADMIN_TOKEN=$(curl -s http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/token \ +# Get a Keycloak admin token from the rossoctl realm +ADMIN_TOKEN=$(curl -s http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/token \ -d "grant_type=password" \ -d "client_id=admin-cli" \ -d "username=admin" \ @@ -683,11 +683,11 @@ ADMIN_TOKEN=$(curl -s http://keycloak-service.keycloak.svc:8080/realms/kagenti/p echo "Admin token length: ${#ADMIN_TOKEN}" -# Look up the agent's client in the kagenti realm. +# Look up the agent's client in the rossoctl realm. # The client ID is the SPIFFE ID (URL-encoded in the query parameter). SPIFFE_ID="spiffe://localtest.me/ns/team1/sa/git-issue-agent" CLIENTS=$(curl -s -H "Authorization: Bearer $ADMIN_TOKEN" \ - "http://keycloak-service.keycloak.svc:8080/admin/realms/kagenti/clients" \ + "http://keycloak-service.keycloak.svc:8080/admin/realms/rossoctl/clients" \ --data-urlencode "clientId=$SPIFFE_ID" --get) INTERNAL_ID=$(echo "$CLIENTS" | jq -r ".[0].id") CLIENT_ID=$(echo "$CLIENTS" | jq -r ".[0].clientId") @@ -703,7 +703,7 @@ echo "Secret length: ${#CLIENT_SECRET}" # Get an OAuth token for the agent TOKEN=$(curl -s -X POST \ - "http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/token" \ + "http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/token" \ -d "grant_type=client_credentials" \ --data-urlencode "client_id=$CLIENT_ID" \ --data-urlencode "client_secret=$CLIENT_SECRET" | jq -r ".access_token") @@ -723,7 +723,7 @@ curl -s --max-time 300 \ "message": { "role": "user", "messageId": "msg-001", - "parts": [{"type": "text", "text": "List 10 open issues in kagenti/kagenti repo"}] + "parts": [{"type": "text", "text": "List 10 open issues in rossoctl/rossoctl repo"}] } } }' | jq @@ -762,7 +762,7 @@ kubectl logs deployment/git-issue-agent -n team1 -c "$SIDECAR" 2>&1 | grep "\[In Expected: ``` -[Inbound] Token validated - issuer: http://keycloak.localtest.me:8080/realms/kagenti, audience: [spiffe://localtest.me/ns/team1/sa/git-issue-agent ...] +[Inbound] Token validated - issuer: http://keycloak.localtest.me:8080/realms/rossoctl, audience: [spiffe://localtest.me/ns/team1/sa/git-issue-agent ...] [Inbound] JWT validation succeeded, forwarding request ``` @@ -775,7 +775,7 @@ kubectl logs deployment/git-issue-agent -n team1 -c "$SIDECAR" 2>&1 | grep "^202 Expected: ``` -[Token Exchange] Token URL: http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/token +[Token Exchange] Token URL: http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/token [Token Exchange] Client ID: spiffe://localtest.me/ns/team1/sa/git-issue-agent [Token Exchange] Audience: github-tool [Token Exchange] Scopes: openid github-tool-aud github-full-access @@ -793,14 +793,14 @@ kubectl delete pod test-client -n team1 --ignore-not-found ## Step 10: Access Control — Alice vs Bob - + Track: https://github.com/rossoctl/rossocortex/issues/139 --> > **Known limitation:** This step requires the authbridge scope forwarding feature -> ([kagenti-extensions#139](https://github.com/kagenti/kagenti-extensions/issues/139)). +> ([rossocortex#139](https://github.com/rossoctl/rossocortex/issues/139)). > Currently, `token_scopes` in the `authproxy-routes` ConfigMap is static per-route, so > all exchanged tokens include `github-full-access` regardless of the original user's > scopes. Once scope forwarding is implemented, Alice's exchanged token will omit @@ -820,7 +820,7 @@ The flow: (`github-full-access` is a realm OPTIONAL scope — Keycloak only includes it when the token request contains `scope=openid github-full-access`) 3. AuthBridge exchanges the token — once scope forwarding is implemented - ([#139](https://github.com/kagenti/kagenti-extensions/issues/139)), the exchanged + ([#139](https://github.com/rossoctl/rossocortex/issues/139)), the exchanged token will preserve the scope difference 4. The GitHub tool checks for `REQUIRED_SCOPE` (`github-full-access`) in the exchanged token 5. Tokens with the scope get the privileged PAT; tokens without get the public-only PAT @@ -850,7 +850,7 @@ jwt_payload() { echo "$p" | base64 -d } -ADMIN_TOKEN=$(curl -s http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/token \ +ADMIN_TOKEN=$(curl -s http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/token \ -d "grant_type=password" \ -d "client_id=admin-cli" \ -d "username=admin" \ @@ -858,7 +858,7 @@ ADMIN_TOKEN=$(curl -s http://keycloak-service.keycloak.svc:8080/realms/kagenti/p SPIFFE_ID="spiffe://localtest.me/ns/team1/sa/git-issue-agent" CLIENTS=$(curl -s -H "Authorization: Bearer $ADMIN_TOKEN" \ - "http://keycloak-service.keycloak.svc:8080/admin/realms/kagenti/clients" \ + "http://keycloak-service.keycloak.svc:8080/admin/realms/rossoctl/clients" \ --data-urlencode "clientId=$SPIFFE_ID" --get) INTERNAL_ID=$(echo "$CLIENTS" | jq -r ".[0].id") CLIENT_ID=$(echo "$CLIENTS" | jq -r ".[0].clientId") @@ -873,7 +873,7 @@ Alice authenticates with Keycloak using `password` grant **without** requesting ```bash ALICE_TOKEN=$(curl -s -X POST \ - "http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/token" \ + "http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/token" \ -d "grant_type=password" \ -d "username=alice" \ -d "password=alice123" \ @@ -899,7 +899,7 @@ curl -s --max-time 300 \ "message": { "role": "user", "messageId": "msg-alice-1", - "parts": [{"type": "text", "text": "List 10 open issues in kagenti/kagenti repo"}] + "parts": [{"type": "text", "text": "List 10 open issues in rossoctl/rossoctl repo"}] } } }' | jq '.result.artifacts[0].parts[0].text' | head -5 @@ -936,7 +936,7 @@ the privileged scope: ```bash BOB_TOKEN=$(curl -s -X POST \ - "http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/token" \ + "http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/token" \ -d "grant_type=password" \ -d "username=bob" \ -d "password=bob123" \ @@ -1030,22 +1030,22 @@ If logs mention `cannot unmarshal !!map into []resolver.yamlRoute`, the file sho kubectl rollout restart deployment/git-issue-agent -n team1 ``` -Longer term, upgrade the Kagenti backend per [kagenti/kagenti#1194](https://github.com/kagenti/kagenti/pull/1194). +Longer term, upgrade the Rossoctl backend per [rossoctl/rossoctl#1194](https://github.com/rossoctl/rossoctl/pull/1194). ### Partial response: Thought and Action only (no issue list) **Symptom:** Chat or `message/send` returns text like -`Thought: … Action: list_issues Action Input: {"owner":"kagenti",…}` but no formatted +`Thought: … Action: list_issues Action Input: {"owner":"rossoctl",…}` but no formatted issue list or `Final Answer:`. -**Cause:** The [git issue agent](https://github.com/kagenti/agent-examples/tree/main/a2a/git_issue_agent) +**Cause:** The [git issue agent](https://github.com/rossoctl/examples/tree/main/a2a/git_issue_agent) (CrewAI + MCP) occasionally completes a turn after the model emits a plan **without** successfully executing the GitHub tool. The GitHub tool log may show `tools/list` (and `initialize`) but **no** `tools/call` / `list_issues` for that attempt. **Demo workaround:** Repeat the same prompt or `curl` a few times until the artifact contains a full answer. Prefer OpenAI over Ollama for stable tool calling when possible -([agent-examples#173](https://github.com/kagenti/agent-examples/issues/173)). +([agent-examples#173](https://github.com/rossoctl/examples/issues/173)). **Optional check** (after a bad run, adjust time window as needed): @@ -1068,7 +1068,7 @@ kubectl get secret keycloak-admin-secret -n team1 # 2. Verify the authbridge-config ConfigMap has the correct realm kubectl get configmap authbridge-config -n team1 -o jsonpath='{.data.KEYCLOAK_REALM}' -# Should show: kagenti +# Should show: rossoctl # 3. Re-apply the demo ConfigMap and restart kubectl apply -f demos/github-issue/k8s/configmaps.yaml @@ -1086,7 +1086,7 @@ kubectl rollout restart deployment/git-issue-agent -n team1 ```bash kubectl set env deployment/git-issue-agent -n team1 -c agent \ MCP_URL="http://github-tool-mcp:9090/mcp" \ - JWKS_URI="http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/certs" + JWKS_URI="http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/certs" kubectl rollout status deployment/git-issue-agent -n team1 --timeout=180s ``` @@ -1104,7 +1104,7 @@ ConfigMap has the correct values: kubectl get configmap envoy-config -n team1 -o jsonpath='{.data.envoy\.yaml}' | grep "timeout:" ``` -If you see `30s` values instead of `300s`, reinstall Kagenti (the installer +If you see `30s` values instead of `300s`, reinstall Rossoctl (the installer creates the correct defaults) and restart the agent: ```bash @@ -1131,7 +1131,7 @@ kubectl logs deployment/git-issue-agent -n team1 -c agent kubectl logs deployment/git-issue-agent -n team1 -c proxy-init --previous 2>/dev/null # Operator-managed registration: -kubectl logs -n kagenti-system deployment/kagenti-controller-manager \ +kubectl logs -n rossoctl-system deployment/rossoctl-controller-manager \ | grep -iE "clientregistration|git-issue-agent" | tail -20 ``` @@ -1163,14 +1163,14 @@ direct curl to the tool gets `Connection reset by peer`. **Symptom:** Tool rejects the exchanged token **Fix:** Verify the tool's environment variables match the Keycloak configuration: -- `ISSUER` should be `http://keycloak.localtest.me:8080/realms/kagenti` +- `ISSUER` should be `http://keycloak.localtest.me:8080/realms/rossoctl` - `AUDIENCE` should be `github-tool` --- ## Cleanup -### Via Kagenti UI +### Via Rossoctl UI 1. Go to the **Agent Catalog**, find `git-issue-agent`, and click **Delete**. 2. Go to the **Tool Catalog**, find `github-tool`, and click **Delete**. diff --git a/authbridge/demos/github-issue/demo.md b/authbridge/demos/github-issue/demo.md index ed04005e9..05f83465e 100644 --- a/authbridge/demos/github-issue/demo.md +++ b/authbridge/demos/github-issue/demo.md @@ -13,7 +13,7 @@ For a simpler getting-started demo without token exchange, see the | Guide | Description | Best For | |-------|-------------|----------| | **[Manual Deployment](demo-manual.md)** | Deploy everything via `kubectl` and YAML manifests | Full control, debugging, understanding internals | -| **[UI Deployment](demo-ui.md)** | Import agent and tool via the Kagenti dashboard | Quick start, UI-driven workflow | +| **[UI Deployment](demo-ui.md)** | Import agent and tool via the Rossoctl dashboard | Quick start, UI-driven workflow | Both guides share the same infrastructure setup (webhook, Keycloak, ConfigMaps) and produce identical AuthBridge security behavior. @@ -25,7 +25,7 @@ produce identical AuthBridge security behavior. 3. **Transparent token exchange** — When the agent calls the GitHub tool, AuthBridge exchanges the token automatically 4. **Subject preservation** — The end user's identity (`sub` claim) is preserved through the exchange 5. **Scope-based access** — The tool uses token scopes to determine public or privileged GitHub API access -6. **Access control (Alice vs Bob)** — Two users with different scopes get different GitHub API access levels: Alice (public only) cannot access private repos, while Bob (privileged) can access both (requires scope forwarding: [kagenti-extensions#139](https://github.com/kagenti/kagenti-extensions/issues/139)) +6. **Access control (Alice vs Bob)** — Two users with different scopes get different GitHub API access levels: Alice (public only) cannot access private repos, while Bob (privileged) can access both (requires scope forwarding: [rossocortex#139](https://github.com/rossoctl/rossocortex/issues/139)) ## Architecture Overview @@ -39,7 +39,7 @@ produce identical AuthBridge security behavior. └──── Keycloak (token exchange) ─────────┘ ``` -The agent pod has two containers (after kagenti-extensions#411): +The agent pod has two containers (after rossocortex#411): - **agent** — the A2A agent (port 8000) - **AuthBridge sidecar** — combined image; container name depends on the resolved AuthBridge mode: @@ -51,7 +51,7 @@ The agent pod has two containers (after kagenti-extensions#411): per-workload by `SPIRE_ENABLED`. Keycloak client registration is operator-managed (no in-pod sidecar); the operator's `ClientRegistrationReconciler` creates a -`kagenti-keycloak-client-credentials-` Secret that the +`rossoctl-keycloak-client-credentials-` Secret that the webhook mounts at `/shared/client-{id,secret}.txt`. ## Key Differences Between Deployment Methods @@ -61,10 +61,10 @@ names, and labels). The only difference is *how* you deploy: | Aspect | Manual | UI | |--------|--------|----| -| **Agent deployment** | `kubectl apply -f` YAML | Kagenti UI "Import New Agent" | -| **Tool deployment** | `kubectl apply -f` YAML | Kagenti UI "Import New Tool" | -| **Image source** | Pre-built (`ghcr.io/kagenti/...`) | Built from source via Shipwright | -| **Primary interaction** | CLI (`curl` via test-client pod) | Kagenti UI chat | +| **Agent deployment** | `kubectl apply -f` YAML | Rossoctl UI "Import New Agent" | +| **Tool deployment** | `kubectl apply -f` YAML | Rossoctl UI "Import New Tool" | +| **Image source** | Pre-built (`ghcr.io/rossoctl/...`) | Built from source via Shipwright | +| **Primary interaction** | CLI (`curl` via test-client pod) | Rossoctl UI chat | | **Env var configuration** | In YAML manifests | UI form + optional `kubectl patch` | Common names used by both: diff --git a/authbridge/demos/github-issue/k8s/configmaps.yaml b/authbridge/demos/github-issue/k8s/configmaps.yaml index a80335b32..20fd81cb0 100644 --- a/authbridge/demos/github-issue/k8s/configmaps.yaml +++ b/authbridge/demos/github-issue/k8s/configmaps.yaml @@ -1,7 +1,7 @@ # Demo-specific ConfigMap overrides for GitHub Issue Agent + AuthBridge # -# The Kagenti installer already creates correct defaults for authbridge-config, -# spiffe-helper-config, and envoy-config (with the kagenti realm). This file +# The Rossoctl installer already creates correct defaults for authbridge-config, +# spiffe-helper-config, and envoy-config (with the rossoctl realm). This file # overrides: # - authbridge-config: Keycloak connection, inbound validation, and outbound exchange settings # - authproxy-routes: per-target token exchange routes @@ -24,7 +24,7 @@ # 2. INBOUND validation: Validates JWT tokens on incoming requests to the agent # 3. OUTBOUND exchange: Exchanges tokens when the agent calls the GitHub tool # -# KEYCLOAK_URL and KEYCLOAK_REALM match the installer defaults (kagenti realm) +# KEYCLOAK_URL and KEYCLOAK_REALM match the installer defaults (rossoctl realm) # and are included because kubectl apply replaces the entire ConfigMap. # TOKEN_URL and ISSUER are auto-derived from KEYCLOAK_URL + KEYCLOAK_REALM. apiVersion: v1 @@ -34,12 +34,12 @@ metadata: namespace: team1 data: KEYCLOAK_URL: "http://keycloak-service.keycloak.svc:8080" - KEYCLOAK_REALM: "kagenti" + KEYCLOAK_REALM: "rossoctl" # TOKEN_URL: Auto-derived from KEYCLOAK_URL + KEYCLOAK_REALM. Only set explicitly # when the token endpoint differs from the standard Keycloak path. - # TOKEN_URL: "http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/token" + # TOKEN_URL: "http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/token" # ISSUER: Set explicitly because the internal KEYCLOAK_URL differs from the frontend URL. - ISSUER: "http://keycloak.localtest.me:8080/realms/kagenti" + ISSUER: "http://keycloak.localtest.me:8080/realms/rossoctl" # Audience validation is automatic — uses CLIENT_ID from /shared/client-id.txt # (written by client-registration or operator). No manual configuration needed. diff --git a/authbridge/demos/github-issue/k8s/git-issue-agent-deployment.yaml b/authbridge/demos/github-issue/k8s/git-issue-agent-deployment.yaml index 93d6bed67..be894d321 100644 --- a/authbridge/demos/github-issue/k8s/git-issue-agent-deployment.yaml +++ b/authbridge/demos/github-issue/k8s/git-issue-agent-deployment.yaml @@ -1,7 +1,7 @@ # GitHub Issue Agent Deployment with AuthBridge # -# This deployment uses the kagenti-operator webhook to automatically inject -# a single combined AuthBridge sidecar (post-kagenti-extensions#411). The exact +# This deployment uses the operator webhook to automatically inject +# a single combined AuthBridge sidecar (post-rossocortex#411). The exact # container shape depends on the resolved AuthBridge mode: # - proxy-sidecar (default): one container "authbridge-proxy" from the # "authbridge" image. spiffe-helper is bundled inside; gated per-workload @@ -13,7 +13,7 @@ # exchange (HTTP), and HTTPS passthrough. # # Keycloak client registration is operator-managed (no in-pod sidecar); -# the operator creates a kagenti-keycloak-client-credentials- Secret +# the operator creates a rossoctl-keycloak-client-credentials- Secret # and the webhook mounts it at /shared/client-{id,secret}.txt. # # The agent container: @@ -22,10 +22,10 @@ # - Token exchange to the tool is handled transparently by the AuthBridge sidecar # # Labels (on Pod template): -# kagenti.io/inject: enabled - Enables AuthBridge sidecar injection -# kagenti.io/spire: enabled - Enables SPIRE-based identity (set to "disabled" if no SPIRE) +# rossoctl.io/inject: enabled - Enables AuthBridge sidecar injection +# rossoctl.io/spire: enabled - Enables SPIRE-based identity (set to "disabled" if no SPIRE) # -# kagenti.io/type is applied automatically by the operator when the +# rossoctl.io/type is applied automatically by the operator when the # AgentRuntime CR (at the end of this file) is created. # # Usage: @@ -55,13 +55,13 @@ spec: metadata: labels: app.kubernetes.io/name: git-issue-agent - kagenti.io/inject: enabled - kagenti.io/spire: enabled + rossoctl.io/inject: enabled + rossoctl.io/spire: enabled spec: serviceAccountName: git-issue-agent containers: - name: agent - image: ghcr.io/kagenti/agent-examples/git-issue-agent:latest + image: ghcr.io/rossoctl/examples/git-issue-agent:latest imagePullPolicy: IfNotPresent ports: - containerPort: 8000 @@ -98,7 +98,7 @@ spec: # Agent service settings # PORT tells the agent where to listen for A2A traffic. - # The kagenti operator may override this via proxy-sidecar + # The rossoctl operator may override this via proxy-sidecar # port-stealing to relocate the agent to a free port. - name: PORT value: "8000" @@ -112,7 +112,7 @@ spec: # JWKS URI for validating incoming tokens from Keycloak - name: JWKS_URI - value: "http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/certs" + value: "http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/certs" resources: limits: cpu: 500m @@ -144,11 +144,11 @@ spec: --- # AgentRuntime triggers operator-managed Keycloak client registration -# (creates kagenti-keycloak-client-credentials- Secret with +# (creates rossoctl-keycloak-client-credentials- Secret with # client-id.txt and client-secret.txt that the authbridge sidecar -# mounts at /shared/). The operator also applies kagenti.io/type=agent +# mounts at /shared/). The operator also applies rossoctl.io/type=agent # to the Deployment and Pod template, enabling webhook sidecar injection. -apiVersion: agent.kagenti.dev/v1alpha1 +apiVersion: agent.rossoctl.dev/v1alpha1 kind: AgentRuntime metadata: name: git-issue-agent diff --git a/authbridge/demos/github-issue/k8s/github-tool-deployment.yaml b/authbridge/demos/github-issue/k8s/github-tool-deployment.yaml index 181af6ee6..8afa82fad 100644 --- a/authbridge/demos/github-issue/k8s/github-tool-deployment.yaml +++ b/authbridge/demos/github-issue/k8s/github-tool-deployment.yaml @@ -42,7 +42,7 @@ spec: spec: containers: - name: github-tool - image: ghcr.io/kagenti/agent-examples/github-tool:latest + image: ghcr.io/rossoctl/examples/github-tool:latest imagePullPolicy: IfNotPresent ports: - containerPort: 9090 @@ -70,9 +70,9 @@ spec: value: "github-full-access" # Keycloak validation settings for incoming tokens - name: ISSUER - value: "http://keycloak.localtest.me:8080/realms/kagenti" + value: "http://keycloak.localtest.me:8080/realms/rossoctl" - name: JWKS_URL - value: "http://keycloak-service.keycloak.svc.cluster.local:8080/realms/kagenti/protocol/openid-connect/certs" + value: "http://keycloak-service.keycloak.svc.cluster.local:8080/realms/rossoctl/protocol/openid-connect/certs" - name: AUDIENCE value: "github-tool" resources: diff --git a/authbridge/demos/github-issue/rbac/Makefile b/authbridge/demos/github-issue/rbac/Makefile index 4dd070c63..380a8166c 100644 --- a/authbridge/demos/github-issue/rbac/Makefile +++ b/authbridge/demos/github-issue/rbac/Makefile @@ -14,7 +14,7 @@ # Prerequisites: # - uv (https://docs.astral.sh/uv/) # - kubectl pointing at the Kind cluster -# - Kind cluster accessible (default name: kagenti) +# - Kind cluster accessible (default name: rossoctl) # - Keycloak running at http://keycloak.localtest.me:8080 # - AGENT_EXAMPLES_DIR set to the agent-examples repo clone (for build-images) # - PRIVILEGED_ACCESS_PAT and PUBLIC_ACCESS_PAT set for the deploy target @@ -41,19 +41,19 @@ help: ## Show this menu (default) $(MAKEFILE_LIST) @printf "\nVariables:\n" @printf " \033[36m%-22s\033[0m %s\n" "NAMESPACE" "target namespace (default: team1)" - @printf " \033[36m%-22s\033[0m %s\n" "KIND_CLUSTER_NAME" "Kind cluster name (default: kagenti)" + @printf " \033[36m%-22s\033[0m %s\n" "KIND_CLUSTER_NAME" "Kind cluster name (default: rossoctl)" @printf " \033[36m%-22s\033[0m %s\n" "AGENT_EXAMPLES_DIR" "path to agent-examples repo clone (required for build-images)" @printf " \033[36m%-22s\033[0m %s\n" "PRIVILEGED_ACCESS_PAT" "GitHub PAT with all-repo access (required for deploy)" @printf " \033[36m%-22s\033[0m %s\n" "PUBLIC_ACCESS_PAT" "GitHub PAT with public-repo access (required for deploy)" @printf " \033[36m%-22s\033[0m %s\n" "RBAC_CONFIG" "RBAC config file (default: rbac/config.yaml)" @printf " \033[36m%-22s\033[0m %s\n" "RBAC_POLICY" "RBAC policy file (default: rbac/policy.yaml)" - @printf " \033[36m%-22s\033[0m %s\n" "PYTHON" "Python interpreter (default: kagenti-extensions/.venv/bin/python)" + @printf " \033[36m%-22s\033[0m %s\n" "PYTHON" "Python interpreter (default: rossocortex/.venv/bin/python)" @printf "\nPrerequisites: uv, kubectl, kind, docker, Keycloak running.\n\n" MAKEFILE_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) NAMESPACE ?= team1 -KIND_CLUSTER_NAME ?= kagenti +KIND_CLUSTER_NAME ?= rossoctl RBAC_CONFIG ?= rbac/config.yaml RBAC_POLICY ?= rbac/policy.yaml AGENT_EXAMPLES_DIR ?= $(MAKEFILE_DIR)../../../../../agent-examples @@ -101,18 +101,18 @@ build-images: ## Build + load agent and tool container images into Kind (requir exit 1; \ } @echo "[*] Building github-tool image ..." - docker build -t ghcr.io/kagenti/agent-examples/github-tool:latest \ + docker build -t ghcr.io/rossoctl/examples/github-tool:latest \ -f $(AGENT_EXAMPLES_DIR)/mcp/github_tool/Dockerfile \ $(AGENT_EXAMPLES_DIR)/mcp/github_tool/ @echo "[*] Building git-issue-agent image ..." - docker build -t ghcr.io/kagenti/agent-examples/git-issue-agent:latest \ + docker build -t ghcr.io/rossoctl/examples/git-issue-agent:latest \ -f $(AGENT_EXAMPLES_DIR)/a2a/git_issue_agent/Dockerfile \ $(AGENT_EXAMPLES_DIR)/a2a/git_issue_agent/ @echo "[*] Loading images into Kind cluster '$(KIND_CLUSTER_NAME)' ..." kind load docker-image --name $(KIND_CLUSTER_NAME) \ - ghcr.io/kagenti/agent-examples/github-tool:latest + ghcr.io/rossoctl/examples/github-tool:latest kind load docker-image --name $(KIND_CLUSTER_NAME) \ - ghcr.io/kagenti/agent-examples/git-issue-agent:latest + ghcr.io/rossoctl/examples/git-issue-agent:latest @echo "[✓] Images built and loaded." # ---------- Setup ---------- @@ -123,7 +123,7 @@ setup-namespace: ## Create namespace and apply webhook ConfigMaps @test -f k8s/configmaps-webhook.yaml && { \ echo "[*] Applying webhook ConfigMaps ..."; \ kubectl apply -f k8s/configmaps-webhook.yaml -n $(NAMESPACE); \ - } || echo "[!] k8s/configmaps-webhook.yaml not found — skipping (Kagenti installer creates these)." + } || echo "[!] k8s/configmaps-webhook.yaml not found — skipping (Rossoctl installer creates these)." @echo "[✓] Namespace ready." setup-keycloak: preflight ## Configure Keycloak: realm, clients, RBAC roles, and users @@ -202,7 +202,7 @@ validate: ## Verify pod readiness and operator-managed client registration && echo "" || echo "(pod not found)" @echo "" @echo "[*] Operator client-registration logs (last 10 relevant lines):" - @kubectl logs -n kagenti-system deployment/kagenti-controller-manager 2>/dev/null \ + @kubectl logs -n rossoctl-system deployment/rossoctl-controller-manager 2>/dev/null \ | grep -iE "clientregistration|git-issue-agent" | tail -10 || echo "(operator not reachable)" @echo "" @echo "[✓] Validation complete — check output above." diff --git a/authbridge/demos/github-issue/rbac/config.yaml b/authbridge/demos/github-issue/rbac/config.yaml index 8c25cee50..4c02a06b6 100644 --- a/authbridge/demos/github-issue/rbac/config.yaml +++ b/authbridge/demos/github-issue/rbac/config.yaml @@ -2,7 +2,7 @@ # Each client can have multiple roles, each role gets its own audience scope # Optional 'secret' parameter: if not provided, Keycloak will auto-generate the client secret clients: - - client_id: "kagenti" + - client_id: "rossoctl" #secret: "demo-ui-secret-for-testing-do-not-use" direct_access_grants: true roles: @@ -33,7 +33,7 @@ realm_roles: # Client audience targets client_audience_targets: - kagenti: + rossoctl: - spiffe://localtest.me/ns/team1/sa/git-issue-agent spiffe://localtest.me/ns/team1/sa/git-issue-agent: - github-tool diff --git a/authbridge/demos/github-issue/rbac/policy.yaml b/authbridge/demos/github-issue/rbac/policy.yaml index 10037c1b5..0d19df970 100644 --- a/authbridge/demos/github-issue/rbac/policy.yaml +++ b/authbridge/demos/github-issue/rbac/policy.yaml @@ -13,12 +13,12 @@ # - “Other technical personnel” are mapped to the realm role tech‑support. # - Access to private and public GitHub repositories requires both client roles on the `github-tool` client: `github-full-access` (covers private) and `github-tool-aud` (covers public). # - Access to public repositories only requires the `github-tool-aud` role. -# - The call chain to reach the GitHub tool is: `kagenti` → `git‑issue‑agent` → `github-tool`. Therefore every user who needs any GitHub access must also receive the entry‑point client role `demo-ui` on `kagenti` and the intermediate role `github-agent` on `git‑issue‑agent`. +# - The call chain to reach the GitHub tool is: `rossoctl` → `git‑issue‑agent` → `github-tool`. Therefore every user who needs any GitHub access must also receive the entry‑point client role `demo-ui` on `rossoctl` and the intermediate role `github-agent` on `git‑issue‑agent`. # - All required client‑role pairs are listed as separate objects, respecting the “both” rule. policy: developer: - - client: kagenti + - client: rossoctl role: demo-ui - client: spiffe://localtest.me/ns/team1/sa/git-issue-agent role: github-agent @@ -27,7 +27,7 @@ policy: - client: github-tool role: github-tool-aud tech-support: - - client: kagenti + - client: rossoctl role: demo-ui - client: spiffe://localtest.me/ns/team1/sa/git-issue-agent role: github-agent diff --git a/authbridge/demos/github-issue/setup_keycloak.py b/authbridge/demos/github-issue/setup_keycloak.py index 7c3c98ae7..451145477 100644 --- a/authbridge/demos/github-issue/setup_keycloak.py +++ b/authbridge/demos/github-issue/setup_keycloak.py @@ -50,7 +50,7 @@ Before provisioning, existing artifacts declared in the config (clients, client roles, realm roles, and client scopes) are deleted so re-running the script starts from a clean slate. Operator-registered scopes (e.g. - agent-*-aud created by the kagenti-operator's ClientRegistrationReconciler) + agent-*-aud created by the operator's ClientRegistrationReconciler) are intentionally left alone. Usage: @@ -97,7 +97,7 @@ # Default configuration KEYCLOAK_URL = os.environ.get("KEYCLOAK_URL", "http://keycloak.localtest.me:8080") -KEYCLOAK_REALM = os.environ.get("KEYCLOAK_REALM", "kagenti") +KEYCLOAK_REALM = os.environ.get("KEYCLOAK_REALM", "rossoctl") KEYCLOAK_ADMIN_USERNAME = os.environ.get("KEYCLOAK_ADMIN_USERNAME", "admin") KEYCLOAK_ADMIN_PASSWORD = os.environ.get("KEYCLOAK_ADMIN_PASSWORD", "admin") @@ -111,7 +111,7 @@ DEFAULT_NAMESPACE = "team1" DEFAULT_SERVICE_ACCOUNT = "git-issue-agent" SPIFFE_TRUST_DOMAIN = "localtest.me" -UI_CLIENT_ID = os.environ.get("UI_CLIENT_ID", "kagenti") +UI_CLIENT_ID = os.environ.get("UI_CLIENT_ID", "rossoctl") DEMO_USERS = [ { @@ -300,7 +300,7 @@ def main_manual(namespace: str = DEFAULT_NAMESPACE, service_account: str = DEFAU user_realm_name="master", ) - # Ensure admin user exists in the kagenti realm so direct token requests succeed + # Ensure admin user exists in the rossoctl realm so direct token requests succeed ensure_admin_in_realm(keycloak_admin, KEYCLOAK_ADMIN_USERNAME, KEYCLOAK_ADMIN_PASSWORD) # --------------------------------------------------------------- @@ -400,7 +400,7 @@ def main_manual(namespace: str = DEFAULT_NAMESPACE, service_account: str = DEFAU print(f"Note: Could not add 'github-full-access' as optional: {e}") # --------------------------------------------------------------- - # Add agent audience scope to the Kagenti UI client + # Add agent audience scope to the Rossoctl UI client # --------------------------------------------------------------- # Keycloak only auto-assigns realm default scopes to NEW clients. # The UI client was created during install (before this scope existed), @@ -409,7 +409,7 @@ def main_manual(namespace: str = DEFAULT_NAMESPACE, service_account: str = DEFAU # reject UI chat requests with "invalid audience". # # TODO: Remove this workaround once the client-registration sidecar - # handles this automatically (kagenti/kagenti-extensions#169). + # handles this automatically (rossoctl/rossocortex#169). print(f"\n--- Adding agent audience scope to UI client '{UI_CLIENT_ID}' ---") ui_client_internal_id = keycloak_admin.get_client_id(UI_CLIENT_ID) if ui_client_internal_id: @@ -475,7 +475,7 @@ def main_manual(namespace: str = DEFAULT_NAMESPACE, service_account: str = DEFAU print(f"\n {user['username']}: {user['description']}") get_or_create_user(keycloak_admin, user) - # The Kagenti backend uses the "admin" realm role for RBAC. Without + # The Rossoctl backend uses the "admin" realm role for RBAC. Without # it, users can log in but see no agents or tools in the UI. print("\n--- Assigning 'admin' realm role to demo users ---") try: @@ -493,7 +493,7 @@ def main_manual(namespace: str = DEFAULT_NAMESPACE, service_account: str = DEFAU else: print( "Warning: 'admin' realm role not found. Demo users will not " - "be able to see agents/tools in the UI. Ensure the Kagenti " + "be able to see agents/tools in the UI. Ensure the Rossoctl " "platform is installed before running this script." ) @@ -530,7 +530,7 @@ def main_manual(namespace: str = DEFAULT_NAMESPACE, service_account: str = DEFAU 6. GitHub tool validates exchanged token and uses appropriate PAT Next steps: - 1. Deploy operator: See https://github.com/kagenti/kagenti-operator for webhook setup + 1. Deploy operator: See https://github.com/rossoctl/operator for webhook setup 2. Apply ConfigMaps: kubectl apply -f demos/github-issue/k8s/configmaps.yaml 3. Create PAT secret: kubectl create secret generic github-tool-secrets -n {namespace} \\ --from-literal=INIT_AUTH_HEADER="Bearer " \\ diff --git a/authbridge/demos/hr-cpex/Makefile b/authbridge/demos/hr-cpex/Makefile index 369538758..46f1fc1b1 100644 --- a/authbridge/demos/hr-cpex/Makefile +++ b/authbridge/demos/hr-cpex/Makefile @@ -9,7 +9,7 @@ # make undeploy # delete the cpex-demo namespace # # Prerequisites: -# - kind cluster (we target `kagenti`; override KIND_CLUSTER) +# - kind cluster (we target `rossoctl`; override KIND_CLUSTER) # - docker / podman # - kubectl # - (chat only) host Ollama on 0.0.0.0 + the right LLM_API_BASE — see the @@ -18,7 +18,7 @@ # All source needed for the demo lives in this directory tree # (hr-mcp-server/, k8s/, agent/). -KIND_CLUSTER ?= kagenti +KIND_CLUSTER ?= rossoctl # Fixed, not overridable: the k8s/*.yaml manifests hardcode the # `cpex-demo` namespace (00-namespace.yaml plus metadata.namespace on # every object), so an override here would create the ConfigMaps in one @@ -62,7 +62,7 @@ MODEL ?= ollama/llama3:latest .DEFAULT_GOAL := help help: ## Show this menu (default) - @printf "\nCPEX demo — runs CPEX/APL policy on the kagenti AuthBridge\n" + @printf "\nCPEX demo — runs CPEX/APL policy on the rossoctl AuthBridge\n" @printf "platform. Self-contained namespace: $(NAMESPACE).\n\n" @printf "Typical run:\n" @printf " \033[1mmake deploy\033[0m\n" diff --git a/authbridge/demos/hr-cpex/README.md b/authbridge/demos/hr-cpex/README.md index 1f4fd03a8..d0051e410 100644 --- a/authbridge/demos/hr-cpex/README.md +++ b/authbridge/demos/hr-cpex/README.md @@ -2,7 +2,7 @@ An LLM **agent** runs as a container exposing **A2A** (`message/send`), with an **authbridge-cpex sidecar enforcing CPEX/APL on the agent's -outbound tool calls** to an MCP backend, on a Kagenti kind cluster. CPEX +outbound tool calls** to an MCP backend, on a Rossoctl kind cluster. CPEX is a transparent **egress guardrail on the agent**: identity, Cedar PDP, RFC 8693 delegation, redaction, PII scanning, session taint, and audit all fire when the agent calls a tool — not at a gateway in front of it. @@ -61,11 +61,11 @@ compose three things a plain PDP does not: ## Prerequisites -The demo runs inside an existing Kagenti environment. It does not -install Kagenti or create a cluster. You need: +The demo runs inside an existing Rossoctl environment. It does not +install Rossoctl or create a cluster. You need: -- A Kagenti kind cluster named `kagenti`. Install it from the - [Kagenti repository][kagenti]. Override `KIND_CLUSTER` in the +- A Rossoctl kind cluster named `rossoctl`. Install it from the + [Rossoctl repository][rossoctl]. Override `KIND_CLUSTER` in the Makefile if yours has a different name. - Docker, to build the three local images (`hr-cpex-agent`, `authbridge-cpex`, `hr-mcp`). They load into kind and are never pushed @@ -86,7 +86,7 @@ checkouts needed. The demo creates one namespace, `cpex-demo`. `make undeploy` removes it cleanly and leaves the rest of the cluster untouched. -[kagenti]: https://github.com/kagenti/kagenti +[rossoctl]: https://github.com/rossoctl/rossoctl ## Quick start @@ -434,7 +434,7 @@ make undeploy # deletes the cpex-demo namespace ## Not covered yet -- **Kagenti operator injection.** Pods deploy via plain `kubectl apply`, +- **Rossoctl operator injection.** Pods deploy via plain `kubectl apply`, not the operator's sidecar-injection path. Promoting cpex into the operator's sidecar list is a separate change. - **abctl TUI.** Would render each Invocation chain visually, including diff --git a/authbridge/demos/hr-cpex/agent/Dockerfile b/authbridge/demos/hr-cpex/agent/Dockerfile index 7acf14e94..266b29b03 100644 --- a/authbridge/demos/hr-cpex/agent/Dockerfile +++ b/authbridge/demos/hr-cpex/agent/Dockerfile @@ -4,7 +4,7 @@ # # Built locally and loaded into kind: # docker build -t hr-cpex-agent:dev . -# kind load docker-image hr-cpex-agent:dev --name kagenti +# kind load docker-image hr-cpex-agent:dev --name rossoctl # The Deployment uses imagePullPolicy: Never so the kubelet takes the # locally-loaded image rather than pulling from a registry. diff --git a/authbridge/demos/hr-cpex/k8s/00-namespace.yaml b/authbridge/demos/hr-cpex/k8s/00-namespace.yaml index e9adc4ae3..4af39d313 100644 --- a/authbridge/demos/hr-cpex/k8s/00-namespace.yaml +++ b/authbridge/demos/hr-cpex/k8s/00-namespace.yaml @@ -1,4 +1,4 @@ -# Demo namespace — self-contained from the rest of kagenti so +# Demo namespace — self-contained from the rest of rossoctl so # `kubectl delete ns cpex-demo` is a clean tear-down. apiVersion: v1 kind: Namespace diff --git a/authbridge/demos/hr-cpex/k8s/20-hr-mcp.yaml b/authbridge/demos/hr-cpex/k8s/20-hr-mcp.yaml index e2fa99f17..bd2bb2a70 100644 --- a/authbridge/demos/hr-cpex/k8s/20-hr-mcp.yaml +++ b/authbridge/demos/hr-cpex/k8s/20-hr-mcp.yaml @@ -4,7 +4,7 @@ # # Image is built locally: `docker build -t hr-mcp:dev .` from the # hr-mcp-server source dir, then `kind load docker-image hr-mcp:dev -# --name kagenti`. The imagePullPolicy: Never below tells the +# --name rossoctl`. The imagePullPolicy: Never below tells the # kubelet to use the locally-loaded image rather than pull from a # registry. diff --git a/authbridge/demos/ibac/Makefile b/authbridge/demos/ibac/Makefile index 04ff4bd9d..488e2472f 100644 --- a/authbridge/demos/ibac/Makefile +++ b/authbridge/demos/ibac/Makefile @@ -1,4 +1,4 @@ -# IBAC demo Makefile — kagenti-UI flow. +# IBAC demo Makefile — rossoctl-UI flow. # # End-to-end: # @@ -6,11 +6,11 @@ # make show-result # render pipeline forensic of last session # make undeploy # remove the demo's resources from team1 # -# IBAC ships in the default authbridge image pulled by the kagenti chart, +# IBAC ships in the default authbridge image pulled by the rossoctl chart, # so this demo only needs to enable the plugin in the rendered ConfigMap. # # Prerequisites: -# - kagenti installed on a kind cluster (this is the operator-flow +# - rossoctl installed on a kind cluster (this is the operator-flow # demo; for plain-kind testing of the IBAC plugin, see commit history # for the standalone variant) # - ollama on the host with llama3.2:3b pulled @@ -25,10 +25,10 @@ .DEFAULT_GOAL := help help: ## Show this menu (default) - @printf "\nIBAC demo — operator-injected agent in kagenti's team1 namespace.\n\n" + @printf "\nIBAC demo — operator-injected agent in rossoctl's team1 namespace.\n\n" @printf "Typical run:\n" @printf " \033[1mmake demo-ibac\033[0m\n" - @printf " ... chat with email-agent in the kagenti UI ...\n" + @printf " ... chat with email-agent in the rossoctl UI ...\n" @printf " \033[1mmake show-result\033[0m\n" @printf " \033[1mmake undeploy\033[0m\n\n" @printf "Targets:\n" @@ -36,14 +36,14 @@ help: ## Show this menu (default) /^[a-zA-Z_-]+:.*## / { printf " \033[36m%-18s\033[0m %s\n", $$1, $$2 }' \ $(MAKEFILE_LIST) @printf "\nVariables:\n" - @printf " \033[36m%-18s\033[0m %s\n" "KIND_CLUSTER_NAME" "kind cluster to load images into (default: kagenti)" + @printf " \033[36m%-18s\033[0m %s\n" "KIND_CLUSTER_NAME" "kind cluster to load images into (default: rossoctl)" @printf " \033[36m%-18s\033[0m %s\n" "NAMESPACE" "agent namespace (default: team1)" @printf " \033[36m%-18s\033[0m %s\n" "AGENT_NAME" "deployment name (default: email-agent)" @printf " \033[36m%-18s\033[0m %s\n" "CONTAINER_RUNTIME" "podman or docker (auto-detected)" - @printf "\nPrerequisites: kagenti install on a kind cluster, ollama on the host\n" + @printf "\nPrerequisites: rossoctl install on a kind cluster, ollama on the host\n" @printf "with llama3.2:3b, kubectl/kind/podman, python3 + PyYAML.\n\n" -KIND_CLUSTER_NAME ?= kagenti +KIND_CLUSTER_NAME ?= rossoctl KIND_NODE ?= $(KIND_CLUSTER_NAME)-control-plane NAMESPACE ?= team1 AGENT_NAME ?= email-agent @@ -66,16 +66,16 @@ LOAD_MARKER := $(STAMP_DIR)/.loaded-this-run # ---------- Pre-flight ---------- -preflight: ## Verify kagenti is installed + tools are available +preflight: ## Verify rossoctl is installed + tools are available - @kubectl get ns kagenti-system >/dev/null 2>&1 || { \ - echo "ERROR: namespace 'kagenti-system' not found — kagenti doesn't appear to be installed."; \ - echo " Install kagenti first (see https://github.com/kagenti/kagenti/blob/main/docs/install.md)"; \ + @kubectl get ns rossoctl-system >/dev/null 2>&1 || { \ + echo "ERROR: namespace 'rossoctl-system' not found — rossoctl doesn't appear to be installed."; \ + echo " Install rossoctl first (see https://github.com/rossoctl/rossoctl/blob/main/docs/install.md)"; \ exit 1; \ } @kubectl get ns $(NAMESPACE) >/dev/null 2>&1 || { \ - echo "ERROR: namespace '$(NAMESPACE)' not found — kagenti's agent namespace is missing."; \ - echo " Did the kagenti install complete? Try: kubectl get ns | grep team"; \ + echo "ERROR: namespace '$(NAMESPACE)' not found — rossoctl's agent namespace is missing."; \ + echo " Did the rossoctl install complete? Try: kubectl get ns | grep team"; \ exit 1; \ } @command -v kind >/dev/null 2>&1 || { echo "ERROR: kind not installed"; exit 1; } @@ -198,8 +198,8 @@ demo-ibac: preflight build-images load-images deploy patch-config ## Build, loa @echo "╔══════════════════════════════════════════════════════════╗" @echo "║ ✅ IBAC demo agent ready ║" @echo "║ ║" - @echo "║ Open the kagenti UI: ║" - @echo "║ http://kagenti-ui.localtest.me:8080 ║" + @echo "║ Open the rossoctl UI: ║" + @echo "║ http://rossoctl-ui.localtest.me:8080 ║" @echo "║ ║" @echo "║ Pick email-agent from the Agents list, then chat: ║" @echo "║ ║" @@ -222,15 +222,15 @@ show-result: build-abctl ## Launch abctl against the agent's session API (inter # ---------- Cleanup ---------- -undeploy: ## Remove demo resources from team1 (kagenti install untouched) +undeploy: ## Remove demo resources from team1 (rossoctl install untouched) -kubectl -n $(NAMESPACE) delete -f k8s/agent.yaml --ignore-not-found -kubectl -n $(NAMESPACE) delete -f k8s/email-server.yaml --ignore-not-found -kubectl -n $(NAMESPACE) delete -f k8s/evil-server.yaml --ignore-not-found -kubectl -n $(NAMESPACE) delete configmap authbridge-config-$(AGENT_NAME) --ignore-not-found - -kubectl -n $(NAMESPACE) delete secret -l kagenti.io/client-name=$(AGENT_NAME) --ignore-not-found + -kubectl -n $(NAMESPACE) delete secret -l rossoctl.io/client-name=$(AGENT_NAME) --ignore-not-found @rm -rf $(STAMP_DIR) @echo "[*] Demo resources removed from $(NAMESPACE)." - @echo " The kagenti install + the namespace itself are untouched." + @echo " The rossoctl install + the namespace itself are untouched." # ---------- Diagnostics ---------- diff --git a/authbridge/demos/ibac/README.md b/authbridge/demos/ibac/README.md index cb1d2f344..fc84fb472 100644 --- a/authbridge/demos/ibac/README.md +++ b/authbridge/demos/ibac/README.md @@ -1,4 +1,4 @@ -# IBAC demo — Intent-Based Access Control via the kagenti UI +# IBAC demo — Intent-Based Access Control via the rossoctl UI > Conceptual overview (threat model, configuration reference, operator deployment guidance): [`authbridge/docs/ibac-plugin.md`](../../docs/ibac-plugin.md). @@ -6,7 +6,7 @@ An email-summarization agent receives a prompt-injection inside one of its email ## Prerequisites -- A [kagenti install](https://github.com/kagenti/kagenti/blob/main/docs/install.md) on a kind cluster (operator + Keycloak + UI). +- A [rossoctl install](https://github.com/rossoctl/rossoctl/blob/main/docs/install.md) on a kind cluster (operator + Keycloak + UI). - ollama on the host with `llama3.2:3b` pulled, reachable from cluster pods at `host.docker.internal:11434`. - `kubectl`, `kind`, `podman` (or `docker`), `python3` with `PyYAML` (`pip3 install --user pyyaml`). @@ -17,7 +17,7 @@ cd authbridge/demos/ibac make demo-ibac # build + load demo images, deploy, patch CM, ready-to-chat banner -# Open http://kagenti-ui.localtest.me:8080, find `email-agent`, chat: +# Open http://rossoctl-ui.localtest.me:8080, find `email-agent`, chat: # "Summarize my emails." make show-result # forensic of the most recent session @@ -37,7 +37,7 @@ Tool call blocked by platform: ## Architecture ``` - kagenti UI (browser) Agent Pod (team1, operator-injected sidecar) + rossoctl UI (browser) Agent Pod (team1, operator-injected sidecar) ┌────────────────────────┐ ┌──────────────────────────────────────────────┐ │ user types │ │ │ │ "Summarize my emails." │ A2A POST│ authbridge-proxy :8000 ──▶ agent :8001 │ diff --git a/authbridge/demos/ibac/agent/main.go b/authbridge/demos/ibac/agent/main.go index e6cc81449..5cc5b75e5 100644 --- a/authbridge/demos/ibac/agent/main.go +++ b/authbridge/demos/ibac/agent/main.go @@ -1,7 +1,7 @@ // Demo email-assistant agent for the IBAC walkthrough. // // Ported from huang195/ibac/agent/main.go with two changes for the -// kagenti deployment shape: +// rossoctl deployment shape: // // 1. Inbound endpoint speaks A2A (JSON-RPC 2.0 message/send) so the // authbridge a2a-parser populates Session.Intents from the user's @@ -589,7 +589,7 @@ type jsonRPCResponse struct { // REQUEST text on response events, which makes the agent's reply // invisible in the platform observability layer. // -// kagenti's backend chat handler accepts both shapes (chat.py:211 +// rossoctl's backend chat handler accepts both shapes (chat.py:211 // handles Task, chat.py:219 handles Message), so emitting a Task // here doesn't break the UI. type a2aTask struct { @@ -622,9 +622,9 @@ type jsonRPCError struct { } // handleAgentCard serves the A2A agent card at -// /.well-known/agent-card.json. The kagenti operator's +// /.well-known/agent-card.json. The rossoctl operator's // AgentCardReconciler fetches this URL through the agent's Service -// and stuffs the result into an AgentCard CR; the kagenti UI's agent +// and stuffs the result into an AgentCard CR; the rossoctl UI's agent // detail page renders that. Without the endpoint the UI shows // "Agent card not available." // @@ -638,7 +638,7 @@ func handleAgentCard(w http.ResponseWriter, r *http.Request) { } // AGENT_PUBLIC_URL is what the UI displays as the agent's // callable address. Defaults to the in-cluster Service URL, - // which is what kagenti UI actually uses for the chat call. + // which is what rossoctl UI actually uses for the chat call. publicURL := envOr("AGENT_PUBLIC_URL", "http://email-agent.team1.svc.cluster.local:8080/") card := map[string]any{ "name": "Email Assistant", @@ -712,7 +712,7 @@ func handleA2A(w http.ResponseWriter, r *http.Request) { } if sessionID == "" { // A2A spec §6.6: when the client omits a contextId, the server - // SHOULD assign one and return it. The kagenti UI currently + // SHOULD assign one and return it. The rossoctl UI currently // sends bare message/send calls without any contextId field; // without this mint, every conversation collapses into the // "default" session bucket on the authbridge side (the rekey- @@ -738,11 +738,11 @@ func handleA2A(w http.ResponseWriter, r *http.Request) { } // writeRPCSuccess emits an A2A v0.3.0 Task response. Both -// status.message AND artifacts carry the agent's reply: the kagenti +// status.message AND artifacts carry the agent's reply: the rossoctl // backend's chat handler reads from status.message (chat.py:211), // while the authbridge a2a-parser's response-side artifact extractor // reads from artifacts[].parts[].text (plugin.go:188-195). Carrying -// the text in both keeps the kagenti UI working AND gets the reply +// the text in both keeps the rossoctl UI working AND gets the reply // into the session-event JSON for abctl / show-result. func writeRPCSuccess(w http.ResponseWriter, id any, sessionID, text string) { taskID := newUUID() diff --git a/authbridge/demos/ibac/go.mod b/authbridge/demos/ibac/go.mod index 6f4aa243e..173606cdf 100644 --- a/authbridge/demos/ibac/go.mod +++ b/authbridge/demos/ibac/go.mod @@ -1,3 +1,3 @@ -module github.com/kagenti/kagenti-extensions/authbridge/demos/ibac +module github.com/rossoctl/rossocortex/authbridge/demos/ibac go 1.24 diff --git a/authbridge/demos/ibac/k8s/agent.yaml b/authbridge/demos/ibac/k8s/agent.yaml index 05d840a03..98f87c83e 100644 --- a/authbridge/demos/ibac/k8s/agent.yaml +++ b/authbridge/demos/ibac/k8s/agent.yaml @@ -1,14 +1,14 @@ -# IBAC demo email-assistant agent — operator-injected, kagenti-UI-discoverable. +# IBAC demo email-assistant agent — operator-injected, rossoctl-UI-discoverable. # -# Required labels for this agent to show up in the kagenti UI: -# kagenti.io/inject: enabled — operator's webhook injects authbridge -# kagenti.io/spire: disabled — demo doesn't depend on SPIRE identity -# protocol.kagenti.io/a2a: "" — declares A2A protocol for the chat flow +# Required labels for this agent to show up in the rossoctl UI: +# rossoctl.io/inject: enabled — operator's webhook injects authbridge +# rossoctl.io/spire: disabled — demo doesn't depend on SPIRE identity +# protocol.rossoctl.io/a2a: "" — declares A2A protocol for the chat flow # # The operator's webhook port-steals: it sees containerPort 8000 here, # rewrites the agent's port to 8001, and sets PORT=8001 + HTTP_PROXY so # the agent's outbound flows through the injected authbridge sidecar's -# forward proxy on :8081. Inbound traffic from the kagenti backend +# forward proxy on :8081. Inbound traffic from the rossoctl backend # hits the Service on :8080, which the operator points at the sidecar's # reverse proxy on :8000, which forwards to the agent on :8001. # @@ -35,7 +35,7 @@ metadata: # Operator's AgentCardReconciler reads this from the workload # (not the Pod template) to know what protocol to fetch the card # under and to confirm the workload is an agent. - protocol.kagenti.io/a2a: "" + protocol.rossoctl.io/a2a: "" spec: replicas: 1 selector: @@ -46,9 +46,9 @@ spec: labels: app.kubernetes.io/name: email-agent app.kubernetes.io/part-of: ibac-demo - kagenti.io/inject: enabled - kagenti.io/spire: disabled - protocol.kagenti.io/a2a: "" + rossoctl.io/inject: enabled + rossoctl.io/spire: disabled + protocol.rossoctl.io/a2a: "" spec: serviceAccountName: email-agent securityContext: @@ -72,7 +72,7 @@ spec: - name: EMAIL_URL value: "http://ibac-email-server.team1.svc.cluster.local:8888" # AGENT_PUBLIC_URL is what the agent advertises in its - # /.well-known/agent-card.json. The kagenti UI uses it + # /.well-known/agent-card.json. The rossoctl UI uses it # for the agent card; default below works for the # standard team1 install. - name: AGENT_PUBLIC_URL @@ -114,7 +114,7 @@ spec: selector: app.kubernetes.io/name: email-agent # Port 8080 → targetPort 8000 mirrors the github-issue-agent demo - # shape. The kagenti backend's /chat endpoint hits the agent's + # shape. The rossoctl backend's /chat endpoint hits the agent's # Service:8080, which the operator wires to the authbridge sidecar's # reverse proxy on :8000. ports: @@ -126,11 +126,11 @@ spec: --- # AgentRuntime triggers operator-managed Keycloak client registration -# (creates kagenti-keycloak-client-credentials- Secret with +# (creates rossoctl-keycloak-client-credentials- Secret with # client-id.txt and client-secret.txt that the authbridge sidecar # mounts at /shared/). Without this CR, jwt-validation has no # audience to validate against and inbound auth falls over. -apiVersion: agent.kagenti.dev/v1alpha1 +apiVersion: agent.rossoctl.dev/v1alpha1 kind: AgentRuntime metadata: name: email-agent @@ -148,4 +148,4 @@ spec: # admission webhook ("an AgentCard already targets Deployment X"). # The operator's CR points at the same Deployment, fetches our # `/.well-known/agent-card.json` endpoint, and stuffs the result -# into the CR's status — which the kagenti UI then displays. +# into the CR's status — which the rossoctl UI then displays. diff --git a/authbridge/demos/ibac/k8s/email-server.yaml b/authbridge/demos/ibac/k8s/email-server.yaml index ec8fec8ca..08a12ea46 100644 --- a/authbridge/demos/ibac/k8s/email-server.yaml +++ b/authbridge/demos/ibac/k8s/email-server.yaml @@ -2,7 +2,7 @@ # # Returns 6 emails on GET /emails — the last one contains a prompt # injection that tells the agent to POST to evil-server. Plain HTTP -# service in team1; not labelled as a kagenti agent or tool, so the +# service in team1; not labelled as a rossoctl agent or tool, so the # operator's webhook leaves it alone. apiVersion: apps/v1 diff --git a/authbridge/demos/ibac/scripts/patch-ibac-config.sh b/authbridge/demos/ibac/scripts/patch-ibac-config.sh index 380eada0e..ce4d4e732 100755 --- a/authbridge/demos/ibac/scripts/patch-ibac-config.sh +++ b/authbridge/demos/ibac/scripts/patch-ibac-config.sh @@ -4,7 +4,7 @@ # # Usage: patch-ibac-config.sh # -# The kagenti operator creates `authbridge-config-` when the +# The rossoctl operator creates `authbridge-config-` when the # agent's pod is admitted (server-side apply, line 682 of pod_mutator.go). # Its default pipeline has only `jwt-validation` inbound and # `token-exchange` outbound. This script: diff --git a/authbridge/demos/mcp-parser/README.md b/authbridge/demos/mcp-parser/README.md index 8a833f133..d58325e3f 100644 --- a/authbridge/demos/mcp-parser/README.md +++ b/authbridge/demos/mcp-parser/README.md @@ -6,10 +6,10 @@ reads, and prompt invocations. ## Prerequisites -- A running Kagenti cluster (Kind or OpenShift) with the Ansible installer +- A running Rossoctl cluster (Kind or OpenShift) with the Ansible installer completed. The mcp-parser plugin works in `envoy-sidecar` and `proxy-sidecar` modes on any cluster type. -- A namespace (e.g., `team1`) labeled with `kagenti-enabled: "true"` for +- A namespace (e.g., `team1`) labeled with `rossoctl-enabled: "true"` for AuthBridge sidecar injection - An MCP-based agent already deployed (e.g., the weather agent from [demo-ui-advanced](../weather-agent/demo-ui-advanced.md)) @@ -57,7 +57,7 @@ for dynamic body buffering to work. Without it, Envoy ignores the response_body_mode: NONE ``` -If you are using the kagenti-operator v0.5.0-alpha.8+, this is already +If you are using the operator v0.5.0-alpha.8+, this is already set in the default `envoy-config` ConfigMap. For earlier versions, patch the ConfigMap manually. @@ -82,13 +82,13 @@ data: plugins: - name: jwt-validation config: - issuer: "http://keycloak.localtest.me:8080/realms/kagenti" + issuer: "http://keycloak.localtest.me:8080/realms/rossoctl" outbound: plugins: - name: token-exchange config: keycloak_url: "http://keycloak-service.keycloak.svc:8080" - keycloak_realm: "kagenti" + keycloak_realm: "rossoctl" identity: type: "spiffe" - mcp-parser @@ -147,12 +147,12 @@ kubectl rollout status deploy/ -n team1 ## Step 4: Send a Request Through the Agent -Use the Kagenti UI or curl to trigger a tool call through the agent. +Use the Rossoctl UI or curl to trigger a tool call through the agent. For the weather agent, simply ask it a weather question — the agent will call the weather-tool-mcp service over MCP (outbound): ```bash -# Via the Kagenti UI: +# Via the Rossoctl UI: # Navigate to the weather agent, type "What's the weather in NYC?" ``` diff --git a/authbridge/demos/mtls/Makefile b/authbridge/demos/mtls/Makefile index 14fd091ca..d9b019cf6 100644 --- a/authbridge/demos/mtls/Makefile +++ b/authbridge/demos/mtls/Makefile @@ -11,17 +11,17 @@ help: @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " \033[36m%-32s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) .PHONY: wait-operator-labels -wait-operator-labels: ## Wait for the operator to apply kagenti.io/type from AgentRuntime CRs +wait-operator-labels: ## Wait for the operator to apply rossoctl.io/type from AgentRuntime CRs @for deploy in $(CALLER) $(CALLEE); do \ echo "[*] Waiting for operator to label $$deploy ..."; \ for i in $$(seq 1 60); do \ val=$$(kubectl -n $(NAMESPACE) get deploy/$$deploy \ - -o jsonpath="{.spec.template.metadata.labels['kagenti.io/type']}" 2>/dev/null); \ + -o jsonpath="{.spec.template.metadata.labels['rossoctl.io/type']}" 2>/dev/null); \ if [ "$$val" = "agent" ]; then echo " ✓ $$deploy labeled"; break; fi; \ sleep 2; \ done; \ val=$$(kubectl -n $(NAMESPACE) get deploy/$$deploy \ - -o jsonpath="{.spec.template.metadata.labels['kagenti.io/type']}" 2>/dev/null); \ + -o jsonpath="{.spec.template.metadata.labels['rossoctl.io/type']}" 2>/dev/null); \ if [ "$$val" != "agent" ]; then \ echo "ERROR: operator did not label $$deploy within 120s"; exit 1; \ fi; \ @@ -63,7 +63,7 @@ undeploy: ## Tear down the demo's resources # envoy-sidecar variant # # Same contract as the proxy-sidecar targets above, but the demo pods -# are fully hand-crafted (no kagenti.io/inject label — see the demo +# are fully hand-crafted (no rossoctl.io/inject label — see the demo # README's "How the demo wires mTLS" section for why) and mTLS is # configured in the Envoy data plane (k8s/envoy-config-mtls.yaml) # rather than at the authbridge-runtime layer. diff --git a/authbridge/demos/mtls/README.md b/authbridge/demos/mtls/README.md index f9554becd..cdd27cf7e 100644 --- a/authbridge/demos/mtls/README.md +++ b/authbridge/demos/mtls/README.md @@ -1,7 +1,7 @@ # mTLS demo — agent-to-agent encryption via SPIRE X.509 SVIDs > **Status.** Both variants are verified end-to-end on a kind + -> kagenti + SPIRE cluster — `make demo-mtls` (proxy-sidecar) and +> rossoctl + SPIRE cluster — `make demo-mtls` (proxy-sidecar) and > `make demo-mtls-envoy*` (envoy-sidecar; see the > [envoy-sidecar variant](#envoy-sidecar-variant) section below). > An earlier revision of this README flagged the proxy-sidecar demo @@ -35,7 +35,7 @@ the token-exchange flows — it just proves the mTLS layer is real. ## Prerequisites -1. **A kagenti install on a kind cluster** with SPIRE enabled. +1. **A rossoctl install on a kind cluster** with SPIRE enabled. 2. **kubectl, kind, podman (or docker)** on PATH. ## Quick start @@ -74,7 +74,7 @@ The `make demo-mtls` target does: workloads pick it up. 3. Restarts the pods so the new config takes effect (mTLS config requires pod restart per the framework hot-reload boundary). -4. Triggers a request from caller → callee through the kagenti UI +4. Triggers a request from caller → callee through the rossoctl UI flow (caller's outbound forward proxy → callee's inbound reverse proxy). 5. Captures cluster traffic via `tcpdump -i any -n -A 'tcp port 8080'` @@ -91,9 +91,9 @@ The `make demo-mtls` target does: and `make demo-mtls-strict-rejects-plain`. - **Cert rotation under load**: tested via unit tests in `authlib/spiffe/x509source_test.go`. -- **kagenti UI integration**: this demo is intentionally pre-UI — +- **rossoctl UI integration**: this demo is intentionally pre-UI — if you want to chat with an mTLS-protected agent, run any other - kagenti demo with `mtls: { mode: strict }` added to its config. + rossoctl demo with `mtls: { mode: strict }` added to its config. - **Ambient mesh interaction**: when ambient is on, ztunnel handles the cross-pod hop and authbridge's mTLS is redundant. This demo doesn't run ambient. Phase 5 will add ambient detection so the @@ -161,7 +161,7 @@ only. ### How the demo wires mTLS -The demo is fully **hand-crafted** — no `kagenti.io/inject` label, +The demo is fully **hand-crafted** — no `rossoctl.io/inject` label, no operator pod injection. This sidesteps both [operator-side notes](#operator-side-notes): no RO `/opt` mount because we control the volumes, no per-agent CM reconciliation because there @@ -192,24 +192,24 @@ Production traffic uses ORIGINAL_DST + iptables — that's a deployment-shape concern, not a mTLS-design concern. Reusing the same TLS blocks (`tls_inspector`, `DownstreamTlsContext`, filter chain match, `UpstreamTlsContext`) in the operator's -`envoy.yaml.tmpl` with ORIGINAL_DST is what the kagenti-operator +`envoy.yaml.tmpl` with ORIGINAL_DST is what the operator follow-up PR does. The follow-up also fixes the RO `/opt` mount and per-agent CM rendering; once it lands, the user sets -`mtlsMode: strict` on the AgentRuntime CR (or in the kagenti UI) +`mtlsMode: strict` on the AgentRuntime CR (or in the rossoctl UI) and the operator wires up the same Envoy YAML this demo ships by hand. ## Operator-side notes Running both variants against a real cluster surfaced two -kagenti-operator items worth knowing about. Both are addressed in -the kagenti-operator companion PR. A third issue (Pod-spec selector +operator items worth knowing about. Both are addressed in +the operator companion PR. A third issue (Pod-spec selector mismatch) was a demo-side oversight already fixed by the manifest updates that landed alongside the envoy-sidecar variant. ### `/opt` mount asymmetry on envoy-sidecar (operator bug, fixed in companion PR) -The kagenti-operator's pod mutator was mounting `svid-output` at +The operator's pod mutator was mounting `svid-output` at `/opt` with `readOnly: true` on envoy-sidecar's `envoy-proxy` container while the proxy-sidecar branch correctly mounted it RW. The in-process spiffe Provider mirror writes `/opt/svid.pem`, @@ -226,11 +226,11 @@ because the file-based `DownstreamTlsContext` / `UpstreamTlsContext` references couldn't resolve. **Affects: envoy-sidecar mode only.** The fix landed in the companion PR — flips the readOnly bit on the `svid-output` volumeMount in `BuildEnvoyProxyContainerWithSpireOption` -(`kagenti-operator/internal/webhook/injector/container_builder.go`). +(`operator/internal/webhook/injector/container_builder.go`). ### Per-agent CMs are operator-owned (by-design; reflected in this PR's script) -The kagenti-operator's pod-mutating webhook builds each per-agent +The operator's pod-mutating webhook builds each per-agent `authbridge-config-` ConfigMap by reading the namespace `authbridge-runtime-config` as baseYAML and overlaying values resolved from the AgentRuntime CR (or defaults when no CR exists). @@ -253,8 +253,8 @@ pod. ### Demo pod enrollment via AgentRuntime -The kagenti-operator's mutating-webhook `objectSelector` requires -`kagenti.io/type` in `[agent, tool]`. The demo manifests include +The operator's mutating-webhook `objectSelector` requires +`rossoctl.io/type` in `[agent, tool]`. The demo manifests include AgentRuntime CRs that enroll each workload — the operator applies the label automatically. The `demo-app` containers set an explicit `runAsUser: 100` (the `curlimages/curl:latest` image runs as the diff --git a/authbridge/demos/mtls/k8s/callee-envoy.yaml b/authbridge/demos/mtls/k8s/callee-envoy.yaml index eed0b8075..0811d1303 100644 --- a/authbridge/demos/mtls/k8s/callee-envoy.yaml +++ b/authbridge/demos/mtls/k8s/callee-envoy.yaml @@ -53,7 +53,7 @@ spec: requests: { cpu: 10m, memory: 32Mi } - name: envoy-proxy - image: ghcr.io/kagenti/kagenti-extensions/authbridge-envoy:latest + image: ghcr.io/rossoctl/rossocortex/authbridge-envoy:latest imagePullPolicy: IfNotPresent args: ["--config", "/etc/authbridge/config.yaml"] ports: diff --git a/authbridge/demos/mtls/k8s/callee.yaml b/authbridge/demos/mtls/k8s/callee.yaml index 4dae6b411..cc30519d8 100644 --- a/authbridge/demos/mtls/k8s/callee.yaml +++ b/authbridge/demos/mtls/k8s/callee.yaml @@ -31,8 +31,8 @@ spec: labels: app.kubernetes.io/name: mtls-callee app.kubernetes.io/part-of: mtls-demo - kagenti.io/inject: enabled - kagenti.io/spire: enabled + rossoctl.io/inject: enabled + rossoctl.io/spire: enabled spec: serviceAccountName: mtls-callee securityContext: @@ -89,9 +89,9 @@ spec: --- # AgentRuntime enrolls this workload with the operator. The operator -# applies kagenti.io/type=agent to the Deployment and Pod template, +# applies rossoctl.io/type=agent to the Deployment and Pod template, # which triggers webhook sidecar injection and Keycloak client registration. -apiVersion: agent.kagenti.dev/v1alpha1 +apiVersion: agent.rossoctl.dev/v1alpha1 kind: AgentRuntime metadata: name: mtls-callee diff --git a/authbridge/demos/mtls/k8s/caller-envoy.yaml b/authbridge/demos/mtls/k8s/caller-envoy.yaml index 6775ef1ce..09441ddda 100644 --- a/authbridge/demos/mtls/k8s/caller-envoy.yaml +++ b/authbridge/demos/mtls/k8s/caller-envoy.yaml @@ -1,6 +1,6 @@ # mTLS demo (envoy-sidecar variant) — caller pod. # -# This is hand-crafted (no kagenti.io/inject label) so we control +# This is hand-crafted (no rossoctl.io/inject label) so we control # every volume mount. Two operator-side bugs (RO /opt mount in # envoy-sidecar mode, runtime CM auto-reconciliation) make the # operator-injected path unworkable today; the operator follow-up @@ -9,7 +9,7 @@ # SPIRE registration happens automatically via the cluster's default # ClusterSPIFFEID (template # spiffe:///ns//sa/ -# ). Any ServiceAccount-bound pod gets an SVID — no kagenti.io/spire +# ). Any ServiceAccount-bound pod gets an SVID — no rossoctl.io/spire # label or operator help required. --- apiVersion: v1 @@ -66,7 +66,7 @@ spec: requests: { cpu: 10m, memory: 32Mi } - name: envoy-proxy - image: ghcr.io/kagenti/kagenti-extensions/authbridge-envoy:latest + image: ghcr.io/rossoctl/rossocortex/authbridge-envoy:latest imagePullPolicy: IfNotPresent # The combined image's entrypoint runs authbridge-envoy # with these args (which it forwards to the binary), then diff --git a/authbridge/demos/mtls/k8s/caller.yaml b/authbridge/demos/mtls/k8s/caller.yaml index e4600077d..403781517 100644 --- a/authbridge/demos/mtls/k8s/caller.yaml +++ b/authbridge/demos/mtls/k8s/caller.yaml @@ -1,7 +1,7 @@ # mTLS demo — caller pod. # -# Operator-injected authbridge sidecar (kagenti.io/inject=enabled); -# SPIRE enabled (kagenti.io/spire=enabled) so spiffe-helper writes +# Operator-injected authbridge sidecar (rossoctl.io/inject=enabled); +# SPIRE enabled (rossoctl.io/spire=enabled) so spiffe-helper writes # the X.509 SVID files authbridge consumes for mTLS. The "demo-app" # container is just curl in a sleep loop — the demo's verify scripts # kubectl-exec into it. @@ -34,8 +34,8 @@ spec: labels: app.kubernetes.io/name: mtls-caller app.kubernetes.io/part-of: mtls-demo - kagenti.io/inject: enabled - kagenti.io/spire: enabled + rossoctl.io/inject: enabled + rossoctl.io/spire: enabled spec: serviceAccountName: mtls-caller securityContext: @@ -96,9 +96,9 @@ spec: --- # AgentRuntime enrolls this workload with the operator. The operator -# applies kagenti.io/type=agent to the Deployment and Pod template, +# applies rossoctl.io/type=agent to the Deployment and Pod template, # which triggers webhook sidecar injection and Keycloak client registration. -apiVersion: agent.kagenti.dev/v1alpha1 +apiVersion: agent.rossoctl.dev/v1alpha1 kind: AgentRuntime metadata: name: mtls-caller diff --git a/authbridge/demos/mtls/k8s/envoy-config-mtls.yaml b/authbridge/demos/mtls/k8s/envoy-config-mtls.yaml index f0f5b0f10..0c5a8714b 100644 --- a/authbridge/demos/mtls/k8s/envoy-config-mtls.yaml +++ b/authbridge/demos/mtls/k8s/envoy-config-mtls.yaml @@ -43,7 +43,7 @@ metadata: namespace: team1 labels: app.kubernetes.io/part-of: mtls-demo - kagenti.io/mtls-mode: permissive + rossoctl.io/mtls-mode: permissive data: envoy.yaml: | admin: @@ -194,7 +194,7 @@ metadata: namespace: team1 labels: app.kubernetes.io/part-of: mtls-demo - kagenti.io/mtls-mode: strict + rossoctl.io/mtls-mode: strict data: envoy.yaml: | admin: diff --git a/authbridge/demos/mtls/scripts/patch-mtls-config.sh b/authbridge/demos/mtls/scripts/patch-mtls-config.sh index e37eb6e02..abbace481 100755 --- a/authbridge/demos/mtls/scripts/patch-mtls-config.sh +++ b/authbridge/demos/mtls/scripts/patch-mtls-config.sh @@ -5,7 +5,7 @@ # # Why the namespace CM and not the per-agent CM: # -# The kagenti-operator's pod-mutating webhook builds each per-agent +# The operator's pod-mutating webhook builds each per-agent # `authbridge-config-` CM by reading the namespace # `authbridge-runtime-config` as baseYAML and overlaying values # resolved from the AgentRuntime CR (or defaults when no CR exists). @@ -40,7 +40,7 @@ echo "[*] Patching $CM in $NAMESPACE with mtls.mode=$MODE" ORIG=$(kubectl -n "$NAMESPACE" get cm "$CM" -o jsonpath='{.data.config\.yaml}') if [[ -z "$ORIG" ]]; then - echo "ERROR: ConfigMap $CM has no config.yaml entry — is the kagenti chart installed in this namespace?" >&2 + echo "ERROR: ConfigMap $CM has no config.yaml entry — is the rossoctl chart installed in this namespace?" >&2 exit 1 fi diff --git a/authbridge/demos/weather-agent/demo-ui-advanced.md b/authbridge/demos/weather-agent/demo-ui-advanced.md index c656ad3a3..00032cf71 100644 --- a/authbridge/demos/weather-agent/demo-ui-advanced.md +++ b/authbridge/demos/weather-agent/demo-ui-advanced.md @@ -19,15 +19,15 @@ the same namespace. ## Prerequisites -- Beginner [demo-ui.md prerequisites](demo-ui.md#prerequisites) (Kagenti UI +- Beginner [demo-ui.md prerequisites](demo-ui.md#prerequisites) (Rossoctl UI reachable, an LLM provider). - In **`team1`**: installer-provided `authbridge-config`, `authbridge-runtime-config`, `spiffe-helper-config`, `envoy-config`. No extra Secrets or ConfigMaps are required up front. **`keycloak-admin-secret` - is not in `team1`.** Operator 0.2+ keeps it in **`kagenti-system`** for + is not in `team1`.** Operator 0.2+ keeps it in **`rossoctl-system`** for client registration; `NotFound` in `team1` is expected: ```bash - kubectl get secret keycloak-admin-secret -n kagenti-system + kubectl get secret keycloak-admin-secret -n rossoctl-system ``` - Python 3.10+ for the Keycloak setup script (Step 1). - For OpenAI: a `team1` Secret named `openai-secret` (created in Step 3). @@ -69,7 +69,7 @@ the optional exchange scope. The script: --- -## Step 2: Import the Weather Tool via Kagenti UI +## Step 2: Import the Weather Tool via Rossoctl UI > ⚠️ **Use the `-advanced` names exactly.** **Tool Name** must be > `weather-tool-advanced` (not `weather-tool`). The Keycloak script in @@ -78,10 +78,10 @@ the optional exchange scope. The script: > `weather-tool-mcp` instead of `weather-tool-advanced-mcp` and the > `MCP_URL` + outbound route in Step 3 won't resolve. -1. Open [Import Tool](http://kagenti-ui.localtest.me:8080/tools/import). +1. Open [Import Tool](http://rossoctl-ui.localtest.me:8080/tools/import). 2. **Namespace**: `team1` · **Tool Name**: `weather-tool-advanced` (exact). 3. **Deploy From Image** · **Container Image**: - `ghcr.io/kagenti/agent-examples/weather_tool` · **Image Tag**: `latest`. + `ghcr.io/rossoctl/examples/weather_tool` · **Image Tag**: `latest`. 4. **MCP Transport Protocol**: `streamable HTTP`. 5. **Enable AuthBridge sidecar injection**: ✅ **check** (advanced demo validates JWTs at the tool's ingress — this is the difference vs. the @@ -100,7 +100,7 @@ kubectl get pods -n team1 -l app.kubernetes.io/name=weather-tool-advanced --- -## Step 3: Import the Weather Agent via Kagenti UI +## Step 3: Import the Weather Agent via Rossoctl UI (If you're using OpenAI, create the secret first — replace `` with your real key; the shell variable expansion shown is intentional and works @@ -124,10 +124,10 @@ kubectl create secret generic openai-secret -n team1 \ Now the UI flow (order matches the actual import form top-to-bottom): -1. Open [Import Agent](http://kagenti-ui.localtest.me:8080/agents/import). +1. Open [Import Agent](http://rossoctl-ui.localtest.me:8080/agents/import). 2. **Namespace**: `team1` · **Agent Name**: `weather-service-advanced` (exact). 3. **Build from Source**: - - Git Repository URL: `https://github.com/kagenti/agent-examples` + - Git Repository URL: `https://github.com/rossoctl/examples` - Git Branch or Tag: `main` - Select Agent: `Weather Service Agent` - Source Subfolder: `a2a/weather_service` @@ -144,8 +144,8 @@ Now the UI flow (order matches the actual import form top-to-bottom): 2. Target Audience: `spiffe://localtest.me/ns/team1/sa/weather-tool-advanced` 3. Token Scopes: `openid weather-tool-exchange-aud` - > If **Outbound Routing Rules** is missing or unresponsive, your Kagenti - > backend may pre-date [kagenti#1194](https://github.com/kagenti/kagenti/pull/1194). + > If **Outbound Routing Rules** is missing or unresponsive, your Rossoctl + > backend may pre-date [rossoctl#1194](https://github.com/rossoctl/rossoctl/pull/1194). > Apply the equivalent ConfigMap with kubectl ( > `kubectl apply -f authbridge/demos/weather-agent/k8s/configmaps-advanced.yaml`) > and skip this expander. Same content, list-shaped `routes.yaml`. @@ -154,8 +154,8 @@ Now the UI flow (order matches the actual import form top-to-bottom): 9. Under **Environment Variables**, click **Import from File/URL** → **From URL**, paste one of the beginner agent's env files, and click **Fetch & Parse**: - - OpenAI: `https://raw.githubusercontent.com/kagenti/agent-examples/refs/heads/main/a2a/weather_service/.env.openai` - - Ollama: `https://raw.githubusercontent.com/kagenti/agent-examples/refs/heads/main/a2a/weather_service/.env.ollama` + - OpenAI: `https://raw.githubusercontent.com/rossoctl/examples/refs/heads/main/a2a/weather_service/.env.openai` + - Ollama: `https://raw.githubusercontent.com/rossoctl/examples/refs/heads/main/a2a/weather_service/.env.ollama` The OpenAI variant adds `LLM_API_KEY` and `OPENAI_API_KEY` as **Secret** entries pointing at `openai-secret`. @@ -179,12 +179,12 @@ python demos/weather-agent/setup_keycloak_weather_advanced.py -n team1 --- -## Step 4: Chat via Kagenti UI +## Step 4: Chat via Rossoctl UI > **Expected catalog quirk.** The **Agent Catalog** shows **two** entries: > `weather-service-advanced` *and* `weather-tool-advanced`. The **Tool > Catalog** is empty. This is by design — the tool's AgentRuntime CR -> uses `type: agent` so the operator applies `kagenti.io/type=agent` +> uses `type: agent` so the operator applies `rossoctl.io/type=agent` > and AuthBridge gets injected (the `injectTools` feature gate is off > by default; see the [kubectl appendix](#operator-gotchas)). Pick > `weather-service-advanced` for chat. @@ -250,14 +250,14 @@ Useful env knobs: |---------|--------------|-----| | UI returns `Error: LLM execution failed: Connection error.` | Agent can't reach its LLM. Ollama not running, or Outbound Ports to Exclude not set to `11434`. `deploy_and_verify_advanced.sh` doesn't catch this — it never calls the LLM. | Start Ollama (`ollama serve` + `ollama pull llama3.2:3b-instruct-fp16`), or re-import with the OpenAI `.env` URL. | | UI returns `Error: No LLM API key configured. Set the LLM_API_KEY environment variable.` | `openai-secret` is empty (often because `$OPENAI_API_KEY` wasn't exported when you ran `kubectl create secret`), or the agent wasn't restarted after fixing it. | Recreate with the literal value, then verify `kubectl get secret openai-secret -n team1 -o jsonpath='{.data.apikey}' \| base64 -d \| wc -c` is non-zero, then `kubectl rollout restart deploy/weather-service-advanced -n team1`. | -| UI: **Outbound Routing Rules** expander missing | Kagenti backend pre-dates [kagenti#1194](https://github.com/kagenti/kagenti/pull/1194) | `kubectl apply -f authbridge/demos/weather-agent/k8s/configmaps-advanced.yaml` and skip the UI step. | +| UI: **Outbound Routing Rules** expander missing | Rossoctl backend pre-dates [rossoctl#1194](https://github.com/rossoctl/rossoctl/pull/1194) | `kubectl apply -f authbridge/demos/weather-agent/k8s/configmaps-advanced.yaml` and skip the UI step. | | UI: agent card not available | AuthBridge failed to load `authproxy-routes` (invalid YAML shape) | See the same section in the [GitHub Issue UI demo](../github-issue/demo-ui.md#agent-card-not-available-in-the-ui). | | `401` on tool MCP from CLI verify | Wrong `target_audience` or scope mapper | `target_audience` must equal the tool SPIFFE; scope `weather-tool-exchange-aud` must map that audience. Re-run `setup_keycloak_weather_advanced.py`. | | `invalid_scope` / `503` from agent | Optional exchange scope not on agent client | Re-run `setup_keycloak_weather_advanced.py -n team1` **after** the agent is running. | | Token exchange denied | Tool client missing `standard.token.exchange.enabled` | Re-run setup with `--wait-tool-client` after the tool pod registers. | -| Tool pod CrashLoopBackOff (`mcp` container) | The `weather_tool` image runs as UID 1001; a `securityContext` overriding the user breaks `uv run` | Use the manifests in `k8s/` as-is (they set `runAsUser/Group/fsGroup: 1001`). On OpenShift, see the [upstream Dockerfile](https://github.com/kagenti/agent-examples/blob/main/mcp/weather_tool/Dockerfile). | +| Tool pod CrashLoopBackOff (`mcp` container) | The `weather_tool` image runs as UID 1001; a `securityContext` overriding the user breaks `uv run` | Use the manifests in `k8s/` as-is (they set `runAsUser/Group/fsGroup: 1001`). On OpenShift, see the [upstream Dockerfile](https://github.com/rossoctl/examples/blob/main/mcp/weather_tool/Dockerfile). | | Tool ingress logs missing `[Inbound]` | Combined sidecar uses different log text | Grep for `Token validated` instead, or increase log window. | -| Deleted the agent or tool, but the Deployment + Service reappear within seconds | The Kagenti backend's reconciliation service finalizes "orphaned" Shipwright builds by re-creating workloads | Also delete the Shipwright `Build` and `BuildRun` (see the [Cleanup](#cleanup) snippet). | +| Deleted the agent or tool, but the Deployment + Service reappear within seconds | The Rossoctl backend's reconciliation service finalizes "orphaned" Shipwright builds by re-creating workloads | Also delete the Shipwright `Build` and `BuildRun` (see the [Cleanup](#cleanup) snippet). | | Chat returns `Cannot connect to MCP weather service at http://weather-tool-advanced-mcp:8000/mcp` | UI import used the standard names (`weather-tool` / `weather-service`) instead of `-advanced`, so the actual Service is `weather-tool-mcp` and `MCP_URL` doesn't resolve | Re-import using the exact `-advanced` names. The Keycloak script from Step 1 also expects those names. | Tool ingress and agent outbound logs (container name varies by AuthBridge mode @@ -272,7 +272,7 @@ kubectl logs deploy/weather-service-advanced -n team1 -c authbridge-proxy 2>&1 | ## Cleanup -Delete via the Kagenti UI (Tool Catalog / Agent Catalog), or via CLI: +Delete via the Rossoctl UI (Tool Catalog / Agent Catalog), or via CLI: ```bash kubectl delete deployment,svc,sa -n team1 \ @@ -280,7 +280,7 @@ kubectl delete deployment,svc,sa -n team1 \ kubectl delete deployment,svc,sa -n team1 \ -l app.kubernetes.io/name=weather-tool-advanced --ignore-not-found -# Also delete the Shipwright Build/BuildRun, otherwise the Kagenti +# Also delete the Shipwright Build/BuildRun, otherwise the Rossoctl # backend's reconciliation service treats them as "orphaned" and # recreates the Deployment + Service + ServiceAccount within seconds: kubectl delete build.shipwright.io,buildrun.shipwright.io -n team1 \ @@ -349,14 +349,14 @@ definitions exist and the secret wins, but it's noisy in `kubectl describe`.) If the demo silently produces unprotected pods, check these: - **`AgentRuntime` is required.** The mutating webhook **skips** AuthBridge - injection unless an `agent.kagenti.dev/v1alpha1` `AgentRuntime` matches the + injection unless an `agent.rossoctl.dev/v1alpha1` `AgentRuntime` matches the Deployment. The k8s manifests here include them; if you build by hand, add them and **restart the Deployment** so new pods are admitted. - **`spec.type: agent`, not `tool`.** With `spec.type: tool` the operator relabels the pod and the `injectTools` feature gate (off by default) controls injection — so the tool ends up with no AuthBridge. This demo uses `spec.type: agent` for the tool's runtime CR. -- **Don't set `kagenti.io/client-registration-inject: "true"`** — that label +- **Don't set `rossoctl.io/client-registration-inject: "true"`** — that label references a removed in-pod sidecar and disables operator-managed registration entirely (#411). diff --git a/authbridge/demos/weather-agent/demo-ui.md b/authbridge/demos/weather-agent/demo-ui.md index 8fad5370c..a0a7b5167 100644 --- a/authbridge/demos/weather-agent/demo-ui.md +++ b/authbridge/demos/weather-agent/demo-ui.md @@ -1,9 +1,9 @@ # Weather Agent Demo with AuthBridge This guide walks through deploying the **Weather Service Agent** with **AuthBridge** -using the **Kagenti UI** for agent and tool deployment. Infrastructure setup +using the **Rossoctl UI** for agent and tool deployment. Infrastructure setup (webhook, Keycloak, ConfigMaps) is done via CLI, while the agent and tool are -imported and deployed through the Kagenti dashboard. +imported and deployed through the Rossoctl dashboard. This is the recommended **getting-started** demo for AuthBridge. It demonstrates inbound JWT validation and automatic identity registration with a simple agent @@ -78,7 +78,7 @@ plugin pipeline in real time while chatting with the agent, see │ │ SPIRE (namespace: │ │ KEYCLOAK (namespace: │ │ │ │ spire) │ │ keycloak) │ │ │ │ │ │ │ │ -│ │ Provides SPIFFE │ │ - kagenti realm │ │ +│ │ Provides SPIFFE │ │ - rossoctl realm │ │ │ │ identities (SVIDs) │ │ - JWKS for inbound │ │ │ │ │ │ JWT validation │ │ │ └──────────────────────┘ └──────────────────────┘ │ @@ -87,16 +87,16 @@ plugin pipeline in real time while chatting with the agent, see ## Prerequisites -Ensure you have completed the Kagenti platform setup as described in the -[Installation Guide](https://github.com/kagenti/kagenti/blob/main/docs/install.md), -including the Kagenti UI. +Ensure you have completed the Rossoctl platform setup as described in the +[Installation Guide](https://github.com/rossoctl/rossoctl/blob/main/docs/install.md), +including the Rossoctl UI. You should also have: -- The Kagenti UI running at `http://kagenti-ui.localtest.me:8080` +- The Rossoctl UI running at `http://rossoctl-ui.localtest.me:8080` - An LLM provider — either: - **Ollama** running locally with a model (e.g. `llama3.2:3b-instruct-fp16`), or - **OpenAI API key** (recommended for most reliable results; see - [agent-examples#173](https://github.com/kagenti/agent-examples/issues/173) for + [agent-examples#173](https://github.com/rossoctl/examples/issues/173) for known Ollama + crewai compatibility issues) --- @@ -108,27 +108,27 @@ In **`team1`**: `authbridge-config`, `authbridge-runtime-config`, `spiffe-helper passthrough; inbound JWT uses issuer/signature checks). **`keycloak-admin-secret` is not in `team1`.** Operator 0.2+ keeps it in -**`kagenti-system`** for client registration. `NotFound` in `team1` is expected: +**`rossoctl-system`** for client registration. `NotFound` in `team1` is expected: ```bash -kubectl get secret keycloak-admin-secret -n kagenti-system +kubectl get secret keycloak-admin-secret -n rossoctl-system ``` -UI login: secret **`kagenti-test-user`** in namespace **`keycloak`** (`admin` + password). -Realm **`kagenti`** is created by the platform installer. +UI login: secret **`rossoctl-test-user`** in namespace **`keycloak`** (`admin` + password). +Realm **`rossoctl`** is created by the platform installer. --- -## Step 1: Import the Weather Tool via Kagenti UI +## Step 1: Import the Weather Tool via Rossoctl UI -1. Navigate to [Import Tool](http://kagenti-ui.localtest.me:8080/tools/import) - in the Kagenti UI. +1. Navigate to [Import Tool](http://rossoctl-ui.localtest.me:8080/tools/import) + in the Rossoctl UI. 2. In the **Namespace** drop-down, choose `team1`, fill *Tool Name* with `weather-tool` (do not use uppercase) 3. Select **Deploy From Image** as the deployment method. -4. For **Container Image**, use `ghcr.io/kagenti/agent-examples/weather_tool`. +4. For **Container Image**, use `ghcr.io/rossoctl/examples/weather_tool`. 5. Pick a corresponding **Image Tag**, replace the default `v0.0.1` with `latest`. @@ -153,17 +153,17 @@ kubectl get pods -n team1 | grep weather-tool --- -## Step 2: Import the Weather Agent via Kagenti UI +## Step 2: Import the Weather Agent via Rossoctl UI -1. Navigate to [Import Agent](http://kagenti-ui.localtest.me:8080/agents/import) - in the Kagenti UI. +1. Navigate to [Import Agent](http://rossoctl-ui.localtest.me:8080/agents/import) + in the Rossoctl UI. 2. In the **Namespace** drop-down, choose `team1`. 3. Select **Build from Source** as the deployment method. 4. Under **Source Repository** select: - - **Git Repository URL**: `https://github.com/kagenti/agent-examples` + - **Git Repository URL**: `https://github.com/rossoctl/examples` - **Git Branch or Tag**: `main` - **Select Agent**: `Weather Service Agent` - **Source Subfolder**: `a2a/weather_service` @@ -184,8 +184,8 @@ kubectl get pods -n team1 | grep weather-tool 11. Under **Environment Variables**, click **Import from File/URL**, Select **From URL** and provide the **URL** from this repo: - - For Ollama: `https://raw.githubusercontent.com/kagenti/agent-examples/refs/heads/main/a2a/weather_service/.env.ollama` - - For OpenAI: `https://raw.githubusercontent.com/kagenti/agent-examples/refs/heads/main/a2a/weather_service/.env.openai` + - For Ollama: `https://raw.githubusercontent.com/rossoctl/examples/refs/heads/main/a2a/weather_service/.env.ollama` + - For OpenAI: `https://raw.githubusercontent.com/rossoctl/examples/refs/heads/main/a2a/weather_service/.env.openai` - Click **Fetch & Parse** — this populates all environment variables including LLM settings and `MCP_URL`. No manual editing is needed. - Click **Import** to set all the env. variables. @@ -236,14 +236,14 @@ weather-tool-7f8c9d6b44-yyyyy 1/1 Running 0 5m ``` > **Note:** AuthBridge ships as a single combined sidecar image (since -> kagenti-extensions#411). `weather-service` runs `agent` + the combined +> rossocortex#411). `weather-service` runs `agent` + the combined > AuthBridge sidecar — `2/2` — regardless of whether SPIRE identity is > enabled. The `spiffe-helper` is bundled inside the combined image and > activated per workload via `SPIRE_ENABLED` (driven by the -> `kagenti.io/spire: enabled` label); it is not a separate container. In +> `rossoctl.io/spire: enabled` label); it is not a separate container. In > `envoy-sidecar` mode the pod is still `2/2` (`agent` + the combined > sidecar) plus a `proxy-init` init container for iptables setup. See the -> [AuthBridge deployment guide](https://github.com/kagenti/kagenti/blob/main/docs/authbridge/deployment-guide.md) +> [AuthBridge deployment guide](https://github.com/rossoctl/rossoctl/blob/main/docs/authbridge/deployment-guide.md) > for the full mode/label reference. ### Verify injected containers @@ -269,14 +269,14 @@ the combined sidecar, not as a separate container. ### Check operator-managed client registration -After kagenti-extensions#411 / kagenti-operator#361, client registration runs -in the kagenti-operator (outside the workload pod). Verify the resulting +After rossocortex#411 / operator#361, client registration runs +in the operator (outside the workload pod). Verify the resulting Secret is mounted into the agent's sidecar: ```bash kubectl get pod -n team1 -l app.kubernetes.io/name=weather-service \ -o jsonpath='{.items[0].spec.volumes[?(@.secret)].secret.secretName}' -# Expect a Secret name starting with: kagenti-keycloak-client-credentials- +# Expect a Secret name starting with: rossoctl-keycloak-client-credentials- ``` Inspect the actual SPIFFE-derived client ID written to /shared/client-id.txt: @@ -289,8 +289,8 @@ kubectl exec deploy/weather-service -n team1 -c "$SIDECAR" -- cat /shared/client ``` Expected — just the SPIFFE ID (the `Created Keycloak client …` log line -now lives in the kagenti-operator's `kagenti-controller-manager` -deployment in `kagenti-system`, not the workload pod): +now lives in the operator's `rossoctl-controller-manager` +deployment in `rossoctl-system`, not the workload pod): ``` spiffe://localtest.me/ns/team1/sa/weather-service @@ -299,7 +299,7 @@ spiffe://localtest.me/ns/team1/sa/weather-service To follow the operator-side registration: ```bash -kubectl logs -n kagenti-system deployment/kagenti-controller-manager \ +kubectl logs -n rossoctl-system deployment/rossoctl-controller-manager \ | grep -i clientregistration | tail -20 ``` @@ -372,14 +372,14 @@ Otherwise, add the annotation after deployment: ```bash kubectl patch deployment weather-service -n team1 --type=merge -p=' -{"spec":{"template":{"metadata":{"annotations":{"kagenti.io/outbound-ports-exclude":"11434"}}}}}' +{"spec":{"template":{"metadata":{"annotations":{"rossoctl.io/outbound-ports-exclude":"11434"}}}}}' kubectl rollout status deployment/weather-service -n team1 --timeout=120s ``` ### Option B: OpenAI Verify the OpenAI secret exists (see the prerequisite note in -[Step 2](#step-2-import-the-weather-agent-via-kagenti-ui)): +[Step 2](#step-2-import-the-weather-agent-via-rossoctl-ui)): ```bash kubectl get secret openai-secret -n team1 @@ -405,9 +405,9 @@ OPENAI_API_KEY=sk-... --- -## Step 5: Chat via Kagenti UI +## Step 5: Chat via Rossoctl UI -1. Navigate to the **Agent Catalog** in the Kagenti UI. +1. Navigate to the **Agent Catalog** in the Rossoctl UI. 2. Select the `team1` namespace. 3. Under **Available Agents**, select `weather-service` and click **View Details**. 4. Verify the **Agent Card** is visible (this confirms the agent is running and @@ -416,7 +416,7 @@ OPENAI_API_KEY=sk-... 6. The agent should respond with current weather information. > **Troubleshooting:** If UI chat returns a `401`, verify that both the UI and -> AuthBridge are configured against the same `kagenti` realm. You can also use +> AuthBridge are configured against the same `rossoctl` realm. You can also use > [Step 6: Test via CLI](#step-6-test-via-cli) to test the AuthBridge flow > independently. @@ -478,8 +478,8 @@ kubectl exec -it test-client -n team1 -- sh Inside the pod, get credentials and send a request: ```bash -# Get a Keycloak admin token from the kagenti realm -ADMIN_TOKEN=$(curl -s http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/token \ +# Get a Keycloak admin token from the rossoctl realm +ADMIN_TOKEN=$(curl -s http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/token \ -d "grant_type=password" \ -d "client_id=admin-cli" \ -d "username=admin" \ @@ -487,10 +487,10 @@ ADMIN_TOKEN=$(curl -s http://keycloak-service.keycloak.svc:8080/realms/kagenti/p echo "Admin token length: ${#ADMIN_TOKEN}" -# Look up the agent's client in the kagenti realm +# Look up the agent's client in the rossoctl realm SPIFFE_ID="spiffe://localtest.me/ns/team1/sa/weather-service" CLIENTS=$(curl -s -H "Authorization: Bearer $ADMIN_TOKEN" \ - "http://keycloak-service.keycloak.svc:8080/admin/realms/kagenti/clients" \ + "http://keycloak-service.keycloak.svc:8080/admin/realms/rossoctl/clients" \ --data-urlencode "clientId=$SPIFFE_ID" --get) CLIENT_ID=$(echo "$CLIENTS" | jq -r ".[0].clientId") CLIENT_SECRET=$(echo "$CLIENTS" | jq -r ".[0].secret") @@ -500,7 +500,7 @@ echo "Secret length: ${#CLIENT_SECRET}" # Get an OAuth token for the agent TOKEN=$(curl -s -X POST \ - "http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/token" \ + "http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/token" \ -d "grant_type=client_credentials" \ --data-urlencode "client_id=$CLIENT_ID" \ --data-urlencode "client_secret=$CLIENT_SECRET" | jq -r ".access_token") @@ -547,7 +547,7 @@ kubectl logs deployment/weather-service -n team1 -c authbridge-proxy 2>&1 | grep Expected: ``` -level=INFO msg="inbound authorized" subject=... clientID=kagenti +level=INFO msg="inbound authorized" subject=... clientID=rossoctl ``` > **Tip:** For detailed debug logs (audience, scopes, request path), enable debug @@ -574,12 +574,12 @@ Keycloak to register the client. **Fix:** ```bash -# 1. Verify the keycloak-admin-secret exists (operator 0.2+ keeps it in kagenti-system) -kubectl get secret keycloak-admin-secret -n kagenti-system +# 1. Verify the keycloak-admin-secret exists (operator 0.2+ keeps it in rossoctl-system) +kubectl get secret keycloak-admin-secret -n rossoctl-system # 2. Verify the authbridge-config ConfigMap has the correct realm kubectl get configmap authbridge-config -n team1 -o jsonpath='{.data.KEYCLOAK_REALM}' -# Should show: kagenti +# Should show: rossoctl # 3. Restart the agent to retry registration kubectl rollout restart deployment/weather-service -n team1 @@ -613,7 +613,7 @@ ConfigMap has the correct values: kubectl get configmap envoy-config -n team1 -o jsonpath='{.data.envoy\.yaml}' | grep "timeout:" ``` -If you see `30s` values instead of `300s`, reinstall Kagenti (the installer +If you see `30s` values instead of `300s`, reinstall Rossoctl (the installer creates the correct defaults) and restart the agent: ```bash @@ -646,7 +646,7 @@ kubectl logs deployment/weather-service -n team1 -c agent # If the issue is operator-managed client registration not finishing, # the workload pod waits on /shared/client-{id,secret}.txt. Inspect: -kubectl logs -n kagenti-system deployment/kagenti-controller-manager \ +kubectl logs -n rossoctl-system deployment/rossoctl-controller-manager \ | grep -iE "clientregistration|weather-service" | tail -20 ``` @@ -654,13 +654,13 @@ kubectl logs -n kagenti-system deployment/kagenti-controller-manager \ ## Switching modes -After kagenti-operator#361 the cluster default is **proxy-sidecar** +After operator#361 the cluster default is **proxy-sidecar** (forward + reverse HTTP proxies, no Envoy, no iptables, no init container). The operator resolves mode per workload from this chain: 1. `AgentRuntime.Spec.AuthBridgeMode` on the workload's CR (canonical). 2. `mode:` field on the namespace-level `authbridge-runtime-config` ConfigMap. -3. Deprecated `kagenti.io/authbridge-mode` pod annotation (still honored). +3. Deprecated `rossoctl.io/authbridge-mode` pod annotation (still honored). 4. Cluster default — `proxy-sidecar`. ### Switch to envoy-sidecar mode @@ -678,7 +678,7 @@ Or, on workloads without an AgentRuntime CR, the deprecated annotation: ```bash kubectl patch deployment weather-service -n team1 --type=merge \ - -p '{"spec":{"template":{"metadata":{"annotations":{"kagenti.io/authbridge-mode":"envoy-sidecar"}}}}}' + -p '{"spec":{"template":{"metadata":{"annotations":{"rossoctl.io/authbridge-mode":"envoy-sidecar"}}}}}' kubectl rollout status deployment weather-service -n team1 --timeout=120s ``` @@ -713,7 +713,7 @@ kubectl rollout restart deployment weather-service -n team1 | Ollama port exclusion | Not needed | Required (annotation) | > **Note:** Proxy-sidecar mode requires the agent to read the `PORT` env var. -> All agents in [kagenti/agent-examples](https://github.com/kagenti/agent-examples) +> All agents in [rossoctl/examples](https://github.com/rossoctl/examples) > support this since v0.1.0-alpha.11. --- @@ -753,7 +753,7 @@ Example (Info lines are always visible; Debug lines appear after SIGUSR1 toggle) ``` level=DEBUG msg="validating inbound JWT" path=/ expectedAudience=spiffe://localtest.me/ns/team1/sa/weather-service -level=INFO msg="inbound authorized" subject=... clientID=kagenti +level=INFO msg="inbound authorized" subject=... clientID=rossoctl level=DEBUG msg="inbound authorized details" path=/ audience="[spiffe://...]" scopes="[openid ...]" level=INFO msg="outbound passthrough" host=weather-tool-mcp.team1.svc.cluster.local:8000 reason="no matching route" ``` @@ -762,7 +762,7 @@ level=INFO msg="outbound passthrough" host=weather-tool-mcp.team1.svc.cluster.l ## Cleanup -### Via Kagenti UI +### Via Rossoctl UI 1. Go to the **Agent Catalog**, find `weather-service`, and click **Delete**. 2. Go to the **Tool Catalog**, find `weather-tool`, and click **Delete**. diff --git a/authbridge/demos/weather-agent/demo-with-abctl.md b/authbridge/demos/weather-agent/demo-with-abctl.md index d07db754b..733ead1f5 100644 --- a/authbridge/demos/weather-agent/demo-with-abctl.md +++ b/authbridge/demos/weather-agent/demo-with-abctl.md @@ -1,17 +1,17 @@ # Weather Agent Walkthrough with `abctl` -This demo extends the standard [Weather Agent demo](./demo-ui.md) with a live view of AuthBridge's plugin pipeline using **`abctl`**, the terminal UI that reads AuthBridge's session API. You'll send chat messages from the Kagenti UI, then watch the request flow through inbound JWT validation → protocol parsers → outbound MCP calls → LLM inference → response — all with token counts, caller identity, request/response pairing, and request-scoped pipeline state visible in real time. +This demo extends the standard [Weather Agent demo](./demo-ui.md) with a live view of AuthBridge's plugin pipeline using **`abctl`**, the terminal UI that reads AuthBridge's session API. You'll send chat messages from the Rossoctl UI, then watch the request flow through inbound JWT validation → protocol parsers → outbound MCP calls → LLM inference → response — all with token counts, caller identity, request/response pairing, and request-scoped pipeline state visible in real time. ## Prerequisites Before starting, complete these in order: -1. **Install Kagenti** (operator + Keycloak + UI + SPIFFE/SPIRE): [Kagenti Installation Guide](https://github.com/kagenti/kagenti/blob/main/docs/install.md). Works on Kind (local) or OpenShift. -2. **Deploy the Weather Agent + Tool** through the Kagenti UI: [Weather Agent Demo with AuthBridge](./demo-ui.md). At the end of that demo you'll have: +1. **Install Rossoctl** (operator + Keycloak + UI + SPIFFE/SPIRE): [Rossoctl Installation Guide](https://github.com/rossoctl/rossoctl/blob/main/docs/install.md). Works on Kind (local) or OpenShift. +2. **Deploy the Weather Agent + Tool** through the Rossoctl UI: [Weather Agent Demo with AuthBridge](./demo-ui.md). At the end of that demo you'll have: - `weather-service` agent running in the `team1` namespace (with AuthBridge sidecars). - `weather-tool-mcp` MCP tool running in `team1`. - Keycloak configured with the agent's `agent-team1-weather-service-aud` scope. - - The Kagenti UI reachable at its route, with a working chat tab for the weather agent. + - The Rossoctl UI reachable at its route, with a working chat tab for the weather agent. Verify by sending one chat message and getting a weather response. Once that works, you're ready for this walkthrough. @@ -39,11 +39,11 @@ Verify by sending one chat message and getting a weather response. Once that wor ## 1. Build `abctl` -`abctl` lives in the `kagenti-extensions` repo. Build it once: +`abctl` lives in the `rossocortex` repo. Build it once: ```sh -git clone https://github.com/kagenti/kagenti-extensions.git -cd kagenti-extensions/authbridge/cmd/abctl +git clone https://github.com/rossoctl/rossocortex.git +cd rossocortex/authbridge/cmd/abctl go build . ``` @@ -74,11 +74,11 @@ Esc backs you out to the Pods pane (and tears down the port-forward) so you can switch pods without quitting. `--endpoint http://...` skips the picker entirely if you already have a port-forward running yourself. -## 3. Send a chat message from the Kagenti UI +## 3. Send a chat message from the Rossoctl UI In a browser: -1. Open the Kagenti UI (route from `kubectl get route kagenti-ui -n kagenti-system` or port-forward). +1. Open the Rossoctl UI (route from `kubectl get route rossoctl-ui -n rossoctl-system` or port-forward). 2. Navigate to the Weather Service agent's chat. 3. Type a question: *"What's the weather in New York?"* 4. Wait for the agent to reply. @@ -104,7 +104,7 @@ Select the row with `↑`/`↓` (or `j`/`k`) and press `Enter` to open the **Eve ╭─ abctl · 4647e888-db99-4739-926e-8bcceeb237c6 ─────────────────────────╮ │ ┌─ IDENTITY ─────────────────────────────────────────────────────────┐ │ │ │ subject alice │ │ -│ │ client kagenti │ │ +│ │ client rossoctl │ │ │ │ scopes openid, email, profile +1 more │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ │ │ @@ -127,7 +127,7 @@ Select the row with `↑`/`↓` (or `j`/`k`) and press `Enter` to open the **Eve What to notice: -- **IDENTITY banner** at the top of the pane — the caller subject (`alice` from Keycloak), the OAuth client (`kagenti`, the UI), and the scopes their token carried. This is per-session, extracted from the inbound JWT. +- **IDENTITY banner** at the top of the pane — the caller subject (`alice` from Keycloak), the OAuth client (`rossoctl`, the UI), and the scopes their token carried. This is per-session, extracted from the inbound JWT. - **Event rows**: - `DIR` — `in` = inbound (caller → agent), `out` = outbound (agent → tool or LLM). - `PHASE` — `req` for request, `└resp` for the matching response (the `└` visually connects a response row back to its paired request). @@ -257,7 +257,7 @@ Press `p` to pause stream rendering. The SSE connection stays open (events don't | Footer shows `✗ failed: …` | `/v1/sessions` fetch failed — check the port-forward is still up and the pod is Ready. | | Sessions appear and disappear | The pod restarted (session store is in-memory). | | `TOKENS` shows `—` on a session | No inference events in that bucket yet, or the server is older than the token-aggregation change (client-side fallback sums from streamed events). | -| Multiple session buckets for one conversation | The UI backend isn't forwarding the A2A `contextId` on subsequent turns. See [kagenti#1481](https://github.com/kagenti/kagenti/pull/1481) for the fix. | +| Multiple session buckets for one conversation | The UI backend isn't forwarding the A2A `contextId` on subsequent turns. See [rossoctl#1481](https://github.com/rossoctl/rossoctl/pull/1481) for the fix. | | Events missing identity | `jwt-validation` didn't run on this code path (e.g. bypass path) or the caller didn't send a Bearer token. | | IDENTITY banner reports `subject —` | The JWT had no `sub` claim (common for Keycloak public-client tokens). Field is still extracted from `azp` / scopes. | diff --git a/authbridge/demos/weather-agent/deploy_and_verify_advanced.sh b/authbridge/demos/weather-agent/deploy_and_verify_advanced.sh index 094580d13..e3f909f25 100755 --- a/authbridge/demos/weather-agent/deploy_and_verify_advanced.sh +++ b/authbridge/demos/weather-agent/deploy_and_verify_advanced.sh @@ -3,7 +3,7 @@ # plus MCP ingress JWT validation on the tool. # # Prerequisites: -# - kubectl configured for a cluster with Kagenti + Keycloak + SPIRE + webhook +# - kubectl configured for a cluster with Rossoctl + Keycloak + SPIRE + webhook # - Namespace team1 (or override NAMESPACE) with installer ConfigMaps # - jq installed on the machine running this script # - Python 3.10+ with AuthBridge/requirements.txt (for setup_keycloak_weather_advanced.py) @@ -32,11 +32,11 @@ SPIFFE_DOMAIN="${SPIFFE_DOMAIN:-localtest.me}" TOOL_SPIFFE="spiffe://${SPIFFE_DOMAIN}/ns/${NAMESPACE}/sa/${TOOL_SA}" AGENT_SPIFFE="spiffe://${SPIFFE_DOMAIN}/ns/${NAMESPACE}/sa/${AGENT_SA}" KC_INTERNAL="${KC_INTERNAL:-http://keycloak-service.keycloak.svc:8080}" -KC_REALM="${KC_REALM:-kagenti}" -# Default matches client created by setup_keycloak_weather_advanced.py (kagenti UI +KC_REALM="${KC_REALM:-rossoctl}" +# Default matches client created by setup_keycloak_weather_advanced.py (rossoctl UI # client often has direct access grants disabled). KC_USER_CLIENT_ID="${KC_USER_CLIENT_ID:-weather-advanced-e2e}" -# For confidential "kagenti" UI client, set KC_USER_CLIENT_SECRET in the environment. +# For confidential "rossoctl" UI client, set KC_USER_CLIENT_SECRET in the environment. # # Rollout: align with spec.progressDeadlineSeconds: 1800 on the tool/agent Deployments (Kind # can exceed 600s default) and with kubectl --timeout below. @@ -59,13 +59,13 @@ if [[ "$SKIP_DEPLOY" != "1" ]]; then log "Deploying weather tool (advanced)..." kubectl apply -f "$SCRIPT_DIR/k8s/weather-tool-advanced.yaml" - log "Applying AgentRuntime (required in Kagenti 0.2+ for AuthBridge injection)..." - if kubectl get crd agentruntimes.agent.kagenti.dev &>/dev/null; then + log "Applying AgentRuntime (required in Rossoctl 0.2+ for AuthBridge injection)..." + if kubectl get crd agentruntimes.agent.rossoctl.dev &>/dev/null; then kubectl apply -f "$SCRIPT_DIR/k8s/agentruntime-weather-tool-advanced.yaml" log "Recreating tool pods so the webhook can inject now that AgentRuntime exists..." kubectl rollout restart "deployment/weather-tool-advanced" -n "$NAMESPACE" else - log "WARNING: agentruntimes.agent.kagenti.dev CRD not found — sidecars may not inject." + log "WARNING: agentruntimes.agent.rossoctl.dev CRD not found — sidecars may not inject." fi kubectl rollout status "deployment/weather-tool-advanced" -n "$NAMESPACE" --timeout="$WEATHER_TOOL_ROLLOUT_TIMEOUT" @@ -88,7 +88,7 @@ if [[ "$SKIP_DEPLOY" != "1" ]]; then log "Deploying weather agent (advanced)..." kubectl apply -f "$SCRIPT_DIR/k8s/weather-service-advanced.yaml" - if kubectl get crd agentruntimes.agent.kagenti.dev &>/dev/null; then + if kubectl get crd agentruntimes.agent.rossoctl.dev &>/dev/null; then kubectl apply -f "$SCRIPT_DIR/k8s/agentruntime-weather-service-advanced.yaml" kubectl rollout restart "deployment/weather-service-advanced" -n "$NAMESPACE" fi @@ -122,8 +122,8 @@ pick_log_container() { local names names=$(kubectl get pod -n "$NAMESPACE" "$pod" -o jsonpath='{.spec.containers[*].name}' | tr ' ' '\n') # Container name depends on the resolved AuthBridge mode (per - # kagenti-operator/internal/webhook/injector/container_builder.go): - # proxy-sidecar (cluster default after kagenti-operator#361): + # operator/internal/webhook/injector/container_builder.go): + # proxy-sidecar (cluster default after operator#361): # AuthBridgeProxyContainerName = "authbridge-proxy" # envoy-sidecar: # EnvoyProxyContainerName = "envoy-proxy" diff --git a/authbridge/demos/weather-agent/k8s/agentruntime-weather-service-advanced.yaml b/authbridge/demos/weather-agent/k8s/agentruntime-weather-service-advanced.yaml index bceb72e56..58c99041a 100644 --- a/authbridge/demos/weather-agent/k8s/agentruntime-weather-service-advanced.yaml +++ b/authbridge/demos/weather-agent/k8s/agentruntime-weather-service-advanced.yaml @@ -1,5 +1,5 @@ # AgentRuntime for the weather A2A agent (AuthBridge + SPIRE injection). -apiVersion: agent.kagenti.dev/v1alpha1 +apiVersion: agent.rossoctl.dev/v1alpha1 kind: AgentRuntime metadata: name: weather-service-advanced diff --git a/authbridge/demos/weather-agent/k8s/agentruntime-weather-tool-advanced.yaml b/authbridge/demos/weather-agent/k8s/agentruntime-weather-tool-advanced.yaml index 3348fb987..aa0a9d4ce 100644 --- a/authbridge/demos/weather-agent/k8s/agentruntime-weather-tool-advanced.yaml +++ b/authbridge/demos/weather-agent/k8s/agentruntime-weather-tool-advanced.yaml @@ -1,14 +1,14 @@ # Binds the weather-tool-advanced Deployment to the platform AuthBridge injection # path. The mutating webhook skips sidecars unless a matching AgentRuntime exists -# (Kagenti 0.2+ / operator chart with pod-mutator). +# (Rossoctl 0.2+ / operator chart with pod-mutator). # # Apply after weather-tool-advanced.yaml (same namespace). -apiVersion: agent.kagenti.dev/v1alpha1 +apiVersion: agent.rossoctl.dev/v1alpha1 kind: AgentRuntime metadata: name: weather-tool-advanced namespace: team1 -# Use type "agent" so the operator does not force pod labels to kagenti.io/type=tool +# Use type "agent" so the operator does not force pod labels to rossoctl.io/type=tool # (which skips injection when the injectTools feature gate is off). The workload # is still the MCP `weather_tool` by container image and Deployment name. spec: diff --git a/authbridge/demos/weather-agent/k8s/configmaps-advanced.yaml b/authbridge/demos/weather-agent/k8s/configmaps-advanced.yaml index e011be335..6df5bde11 100644 --- a/authbridge/demos/weather-agent/k8s/configmaps-advanced.yaml +++ b/authbridge/demos/weather-agent/k8s/configmaps-advanced.yaml @@ -1,11 +1,11 @@ # AuthBridge overrides for the Weather advanced demo (token exchange to tool). # -# Apply after the Kagenti platform has created the namespace and baseline +# Apply after the Rossoctl platform has created the namespace and baseline # authbridge-config / envoy-config / spiffe-helper-config ConfigMaps. # # `kubectl apply` replaces the entire `authbridge-config` ConfigMap. The `data` below -# therefore **includes the same keys** as `charts/kagenti/templates/agent-namespaces.yaml` -# in the kagenti repo (defaults: keycloak in `keycloak` namespace, realm `kagenti`, split +# therefore **includes the same keys** as `charts/rossoctl/templates/agent-namespaces.yaml` +# in the rossoctl repo (defaults: keycloak in `keycloak` namespace, realm `rossoctl`, split # horizon `publicUrl`), plus the demo's explicit TOKEN_URL / JWKS_URL for the ext_proc # go-processor. If your install overrides `authBridge.clientAuthType`, `keycloak.publicUrl`, # or similar, merge those values into this manifest before applying. @@ -32,18 +32,18 @@ metadata: name: authbridge-config namespace: team1 data: - # — Same baseline keys as kagenti chart (agent-namespaces authbridge-config) — + # — Same baseline keys as rossoctl chart (agent-namespaces authbridge-config) — KEYCLOAK_URL: "http://keycloak-service.keycloak.svc:8080" - KEYCLOAK_REALM: "kagenti" + KEYCLOAK_REALM: "rossoctl" KEYCLOAK_NAMESPACE: "keycloak" - ISSUER: "http://keycloak.localtest.me:8080/realms/kagenti" + ISSUER: "http://keycloak.localtest.me:8080/realms/rossoctl" SPIRE_ENABLED: "true" CLIENT_AUTH_TYPE: "client-secret" SPIFFE_IDP_ALIAS: "spire-spiffe" - EXPECTED_AUDIENCE: "http://keycloak.localtest.me:8080/realms/kagenti" + EXPECTED_AUDIENCE: "http://keycloak.localtest.me:8080/realms/rossoctl" # — Weather advanced: explicit token + JWKS (ext_proc) — - TOKEN_URL: "http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/token" - JWKS_URL: "http://keycloak-service.keycloak.svc:8080/realms/kagenti/protocol/openid-connect/certs" + TOKEN_URL: "http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/token" + JWKS_URL: "http://keycloak-service.keycloak.svc:8080/realms/rossoctl/protocol/openid-connect/certs" --- apiVersion: v1 kind: ConfigMap diff --git a/authbridge/demos/weather-agent/k8s/weather-service-advanced.yaml b/authbridge/demos/weather-agent/k8s/weather-service-advanced.yaml index 2b7026569..0f1199e64 100644 --- a/authbridge/demos/weather-agent/k8s/weather-service-advanced.yaml +++ b/authbridge/demos/weather-agent/k8s/weather-service-advanced.yaml @@ -32,12 +32,12 @@ spec: template: metadata: labels: - protocol.kagenti.io/a2a: "" + protocol.rossoctl.io/a2a: "" app.kubernetes.io/name: weather-service-advanced - kagenti.io/inject: enabled - kagenti.io/spire: enabled + rossoctl.io/inject: enabled + rossoctl.io/spire: enabled annotations: - kagenti.io/outbound-ports-exclude: "11434" + rossoctl.io/outbound-ports-exclude: "11434" spec: serviceAccountName: weather-service-advanced securityContext: @@ -49,7 +49,7 @@ spec: type: RuntimeDefault containers: - name: agent - image: ghcr.io/kagenti/agent-examples/weather_service:latest + image: ghcr.io/rossoctl/examples/weather_service:latest imagePullPolicy: IfNotPresent securityContext: allowPrivilegeEscalation: false diff --git a/authbridge/demos/weather-agent/k8s/weather-tool-advanced.yaml b/authbridge/demos/weather-agent/k8s/weather-tool-advanced.yaml index d0f7e0b98..7f021d71a 100644 --- a/authbridge/demos/weather-agent/k8s/weather-tool-advanced.yaml +++ b/authbridge/demos/weather-agent/k8s/weather-tool-advanced.yaml @@ -1,14 +1,14 @@ # Weather MCP tool with AuthBridge + SPIRE (inbound JWT at Envoy before the MCP server). # -# Prerequisites: Kagenti platform, webhook, SPIRE, namespace team1, ConfigMaps +# Prerequisites: Rossoctl platform, webhook, SPIRE, namespace team1, ConfigMaps # from the installer (authbridge-config, envoy-config, spiffe-helper-config). # # The MCP server listens on port 8000. AuthBridge ext_proc listens on 9090 # inside the pod, so there is no port collision (unlike the GitHub tool on 9090). # -# The kagenti-operator's AgentRuntime CR (agentruntime-weather-tool-advanced.yaml) +# The operator's AgentRuntime CR (agentruntime-weather-tool-advanced.yaml) # enrolls this workload and triggers AuthBridge sidecar injection. The -# AgentRuntime uses type "agent" so the operator applies kagenti.io/type=agent +# AgentRuntime uses type "agent" so the operator applies rossoctl.io/type=agent # to the pod (the injectTools feature gate is off by default). This workload # is still the weather MCP tool by image and Deployment name; it is enrolled # as type "agent" so client-registration runs and registers the tool's @@ -31,8 +31,8 @@ metadata: labels: app.kubernetes.io/name: weather-tool-advanced app.kubernetes.io/component: mcp-tool - protocol.kagenti.io/mcp: "" - kagenti.io/transport: streamable_http + protocol.rossoctl.io/mcp: "" + rossoctl.io/transport: streamable_http spec: # Default Deployment progress deadline is 600s; cold ghcr + webhook restart + many # sidecars in Kind can exceed that before the old ReplicaSet pod drains. @@ -50,10 +50,10 @@ spec: labels: app.kubernetes.io/name: weather-tool-advanced app.kubernetes.io/component: mcp-tool - protocol.kagenti.io/mcp: "" - kagenti.io/transport: streamable_http - kagenti.io/inject: enabled - kagenti.io/spire: enabled + protocol.rossoctl.io/mcp: "" + rossoctl.io/transport: streamable_http + rossoctl.io/inject: enabled + rossoctl.io/spire: enabled spec: serviceAccountName: weather-tool-advanced # Must match the image (Dockerfile USER 1001). Pod-level runAsNonRoot alone can @@ -68,7 +68,7 @@ spec: type: RuntimeDefault containers: - name: mcp - image: ghcr.io/kagenti/agent-examples/weather_tool:latest + image: ghcr.io/rossoctl/examples/weather_tool:latest imagePullPolicy: IfNotPresent env: - name: PORT @@ -117,7 +117,7 @@ metadata: namespace: team1 labels: app.kubernetes.io/name: weather-tool-advanced - protocol.kagenti.io/mcp: "" + protocol.rossoctl.io/mcp: "" spec: type: ClusterIP selector: diff --git a/authbridge/demos/weather-agent/setup_keycloak_weather_advanced.py b/authbridge/demos/weather-agent/setup_keycloak_weather_advanced.py index 6a317bbb5..c8ca9e9f6 100644 --- a/authbridge/demos/weather-agent/setup_keycloak_weather_advanced.py +++ b/authbridge/demos/weather-agent/setup_keycloak_weather_advanced.py @@ -25,12 +25,12 @@ from keycloak import KeycloakAdmin, KeycloakGetError, KeycloakPostError KEYCLOAK_URL = os.environ.get("KEYCLOAK_URL", "http://keycloak.localtest.me:8080") -KEYCLOAK_REALM = os.environ.get("KEYCLOAK_REALM", "kagenti") +KEYCLOAK_REALM = os.environ.get("KEYCLOAK_REALM", "rossoctl") KEYCLOAK_ADMIN_USERNAME = os.environ.get("KEYCLOAK_ADMIN_USERNAME", "admin") KEYCLOAK_ADMIN_PASSWORD = os.environ.get("KEYCLOAK_ADMIN_PASSWORD", "admin") SPIFFE_TRUST_DOMAIN = "localtest.me" -UI_CLIENT_ID = os.environ.get("UI_CLIENT_ID", "kagenti") +UI_CLIENT_ID = os.environ.get("UI_CLIENT_ID", "rossoctl") # Public client for automated tests (ROPC / direct access) — the UI client often # has direct access grants disabled. diff --git a/authbridge/docs/framework-architecture.md b/authbridge/docs/framework-architecture.md index 74cb3ee6c..648446ee5 100644 --- a/authbridge/docs/framework-architecture.md +++ b/authbridge/docs/framework-architecture.md @@ -385,7 +385,7 @@ Returning `Reject` from `OnRequest` halts the request pipeline; from `OnResponse "message": "Bearer token required", "description": "No Authorization header present", "plugin": "jwt-validation", - "details": { "realm": "kagenti" } + "details": { "realm": "rossoctl" } } ``` @@ -397,7 +397,7 @@ pipeline.DenyStatus(451, "policy.forbidden", "unavailable for legal reasons") pipeline.DenyWithDetails("policy.rate-limited", "quota hit", map[string]any{ "remaining": 0, "window": "1h", }) -pipeline.Challenge("kagenti", "Authorization required") // 401 + WWW-Authenticate +pipeline.Challenge("rossoctl", "Authorization required") // 401 + WWW-Authenticate pipeline.RateLimited(30*time.Second, "", "slow down") // 429 + Retry-After ``` @@ -664,7 +664,7 @@ The pipeline **does not own**: |---|---|---| | HTTP wire protocol (ext_proc gRPC, ext_authz, reverse/forward proxy) | `cmd/authbridge/listener/` | Each mode speaks a different wire; pipeline stays protocol-free | | Body buffering negotiation (`ProcessingMode: BUFFERED`) | Listener reads `Pipeline.NeedsBody()` | Only listener can respond to the ext_proc handshake | -| JWT issuance, client registration, Keycloak admin calls | Outside the pipeline (agent sidecars / kagenti-operator) | Async concerns happening before/after any request flow | +| JWT issuance, client registration, Keycloak admin calls | Outside the pipeline (agent sidecars / operator) | Async concerns happening before/after any request flow | | Session store writes (`Store.Append`) | Listener, called after each phase | Plugins see only the read-only `SessionView` | | SSE streaming of events to abctl | `authlib/sessionapi` | Observability API, not a plugin concern | | **mTLS handshake + peer-cert verification** | **`authlib/listener/...` (proxy-sidecar) using `authlib/tls` + `authlib/spiffe`** | **Transport-level concern; happens before any plugin sees a decrypted HTTP message** | diff --git a/authbridge/docs/idp-plugin-contract.md b/authbridge/docs/idp-plugin-contract.md index 9adfc63ba..564d1615d 100644 --- a/authbridge/docs/idp-plugin-contract.md +++ b/authbridge/docs/idp-plugin-contract.md @@ -1,6 +1,6 @@ # IdP-Agnostic Token Exchange Plugin Contract -> **Status:** Implemented — RHAIENG-5681 / kagenti-extensions#481 +> **Status:** Implemented — RHAIENG-5681 / rossocortex#481 > > This document defines the contract that an Identity Provider (IdP) > plugin must satisfy for the AuthBridge token exchange pipeline. @@ -50,8 +50,8 @@ Create a single file — no changes to core plugin code required: package tokenexchange import ( - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/tokenexchange/exchange" - fwspiffe "github.com/kagenti/kagenti-extensions/authbridge/authlib/spiffe" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/tokenexchange/exchange" + fwspiffe "github.com/rossoctl/rossocortex/authbridge/authlib/spiffe" ) type oktaProvider struct{} diff --git a/authbridge/docs/litellm-budgettrack-plugin.md b/authbridge/docs/litellm-budgettrack-plugin.md index fcf5ec80a..ec6dc301c 100644 --- a/authbridge/docs/litellm-budgettrack-plugin.md +++ b/authbridge/docs/litellm-budgettrack-plugin.md @@ -2,7 +2,7 @@ Design document for the `litellm-budget-track` AuthBridge inbound pipeline plugin. -**Issue:** https://github.com/kagenti/kagenti/issues/2177 +**Issue:** https://github.com/rossoctl/rossoctl/issues/2177 ## Overview @@ -112,7 +112,7 @@ The registration file uses the standard build-tag pattern: package main -import _ "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins/litellm_budgettrack" +import _ "github.com/rossoctl/rossocortex/authbridge/authlib/plugins/litellm_budgettrack" ``` ## Integration with RossoCortex diff --git a/authbridge/docs/plugin-reference.md b/authbridge/docs/plugin-reference.md index 09edb7e76..4dc1f8737 100644 --- a/authbridge/docs/plugin-reference.md +++ b/authbridge/docs/plugin-reference.md @@ -433,7 +433,7 @@ import ( "errors" "fmt" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // myPluginConfig is the plugin's private config schema. Fields are JSON- @@ -889,7 +889,7 @@ the types in [`authlib/pipeline/content.go`](../authlib/pipeline/content.go). ### Consuming content in a guardrail ```go -import "github.com/kagenti/kagenti-extensions/authbridge/authlib/contracts" +import "github.com/rossoctl/rossocortex/authbridge/authlib/contracts" func (p *JailbreakDetector) OnRequest(_ context.Context, pctx *pipeline.Context) pipeline.Action { for _, src := range pctx.ContentSources() { diff --git a/authbridge/docs/plugin-tutorial.md b/authbridge/docs/plugin-tutorial.md index 544b3e1bc..81e064846 100644 --- a/authbridge/docs/plugin-tutorial.md +++ b/authbridge/docs/plugin-tutorial.md @@ -33,7 +33,7 @@ import ( "context" "log/slog" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) type HelloLog struct{} @@ -255,8 +255,8 @@ imports the registry instead of sharing its package: package myplugin import ( - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/plugins" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/plugins" ) type MyPlugin struct{} @@ -279,7 +279,7 @@ package main import _ "github.com/acme/my-plugin" ``` -No fork of kagenti-extensions required. +No fork of rossocortex required. ## Step 7 — Test your plugin @@ -330,7 +330,7 @@ Minimal example for an Inference-like parser whose extension stores `Messages []struct{ Role, Content string }`: ```go -import "github.com/kagenti/kagenti-extensions/authbridge/authlib/contracts" +import "github.com/rossoctl/rossocortex/authbridge/authlib/contracts" // Compile-time assertion — catches interface drift at build time. var _ contracts.ContentSource = (*MyExtension)(nil) diff --git a/authbridge/docs/sparc-plugin.md b/authbridge/docs/sparc-plugin.md index af2badb1d..e67bc7a98 100644 --- a/authbridge/docs/sparc-plugin.md +++ b/authbridge/docs/sparc-plugin.md @@ -35,7 +35,7 @@ off), the plugin **skips** (`no_inference_context`) rather than reflect on parti The verdict is returned to the agent in the shape it expects, selected by `enforcement`: -- **`mcp` (default — the kagenti norm).** Gate the outbound MCP `tools/call`. The tool call +- **`mcp` (default — the rossoctl norm).** Gate the outbound MCP `tools/call`. The tool call comes from the MCP request; conversation + tool specs are correlated from the session's most recent inference request (robust to LLM streaming). On a reflected reject, return SPARC's clarification as a **JSON-RPC MCP tool result** (`Reject` + `Violation{Status:200, Body}`); @@ -76,7 +76,7 @@ hits an unreachable reflector (and falls back to `fail_policy`). It's one comman ```bash cd authbridge/sparc-service/deploy export WX_API_KEY=... WX_PROJECT_ID=... # or PROVIDER=ollama, openai, ... -make install # deploys into kagenti-system by default +make install # deploys into rossoctl-system by default ``` See [`sparc-service/deploy/README.md`](../sparc-service/deploy/README.md) for providers, the @@ -91,7 +91,7 @@ pipeline: plugins: - name: sparc config: - reflector_endpoint: "http://sparc-service.kagenti-system.svc:8090" + reflector_endpoint: "http://sparc-service.rossoctl-system.svc:8090" enforcement: "mcp" # mcp | inference track: "fast_track" # fast_track|slow_track|syntax|spec_free|transformations_only on_reject_action: "reflect" # observe | reflect | deny @@ -156,7 +156,7 @@ explanations/corrections. The reflection service is an **in-cluster backend** — same trust model as the authbridge session API (`:9094`): no ingress, never exposed publicly. Its `/reflect` endpoint is unauthenticated by -default and runs outside the agent-side ambient mesh (`kagenti.io/inject: disabled`), so it makes +default and runs outside the agent-side ambient mesh (`rossoctl.io/inject: disabled`), so it makes its own egress to the LLM provider. Treat the cluster network boundary as the control: restrict who can reach it with a `NetworkPolicy` (allow only the authbridge sidecars), since any pod that can POST to `/reflect` can trigger LLM calls billed to the configured credentials. For an extra diff --git a/authbridge/docs/superpowers/plans/2026-05-22-authbridge-go-spiffe-sdk.md b/authbridge/docs/superpowers/plans/2026-05-22-authbridge-go-spiffe-sdk.md index 08791c2ba..5894478ae 100644 --- a/authbridge/docs/superpowers/plans/2026-05-22-authbridge-go-spiffe-sdk.md +++ b/authbridge/docs/superpowers/plans/2026-05-22-authbridge-go-spiffe-sdk.md @@ -1382,7 +1382,7 @@ func BuildWithSPIFFE(entries []config.PluginEntry, p *spiffe.Provider, opts ...p The existing `Build` function is unchanged; new wiring uses `BuildWithSPIFFE`. -> Import for `spiffe` package: `import "github.com/kagenti/kagenti-extensions/authbridge/authlib/spiffe"`. Verify there's no cycle (spiffe should not import plugins; plugins importing spiffe is fine). +> Import for `spiffe` package: `import "github.com/rossoctl/rossocortex/authbridge/authlib/spiffe"`. Verify there's no cycle (spiffe should not import plugins; plugins importing spiffe is fine). - [ ] **Step 4: Run tests** @@ -1446,7 +1446,7 @@ In `authlib/plugins/tokenexchange/plugin.go`: ```go import ( - fwspiffe "github.com/kagenti/kagenti-extensions/authbridge/authlib/spiffe" + fwspiffe "github.com/rossoctl/rossocortex/authbridge/authlib/spiffe" ) // Add field to TokenExchange struct: @@ -1767,7 +1767,7 @@ Expected: PASS. If any package still imports `FileX509Source` / `NewFileX509Sour git commit -s -m "refactor(spiffe): delete FileX509Source No runtime caller after the Provider/workloadX509 migration. Deletion -follows the kagenti CLAUDE.md guidance to remove unused code rather +follows the rossoctl CLAUDE.md guidance to remove unused code rather than leave it behind. Assisted-By: Claude (Anthropic AI) " @@ -1874,7 +1874,7 @@ Assisted-By: Claude (Anthropic AI) " - [ ] PR description includes: - Spec link: `authbridge/docs/superpowers/specs/2026-05-22-authbridge-go-spiffe-sdk-design.md` - Manual-verification checklist results - - Note on chart sequencing: "kagenti chart PR adding `spiffe.jwt_audience` rendering must merge first" + - Note on chart sequencing: "rossoctl chart PR adding `spiffe.jwt_audience` rendering must merge first" - Image-size delta (~15-20MB compressed reduction per image) - `Assisted-By: Claude Code` footer diff --git a/authbridge/docs/superpowers/plans/2026-05-28-abctl-pipeline-edit.md b/authbridge/docs/superpowers/plans/2026-05-28-abctl-pipeline-edit.md index cf210e628..32f258f7f 100644 --- a/authbridge/docs/superpowers/plans/2026-05-28-abctl-pipeline-edit.md +++ b/authbridge/docs/superpowers/plans/2026-05-28-abctl-pipeline-edit.md @@ -205,7 +205,7 @@ Expected: all tests pass, vet clean. The new `TestKubectlPortForward_StatusEndpo ### Step 6: Commit ```bash -cd /Users/haihuang/works/go/src/github.com/kagenti/kagenti-extensions +cd /Users/haihuang/works/go/src/github.com/rossoctl/rossocortex git add authbridge/cmd/abctl/cluster/portforward.go \ authbridge/cmd/abctl/cluster/portforward_test.go \ authbridge/cmd/abctl/tui/picker_test.go @@ -458,7 +458,7 @@ Expected: all 4 tests PASS, vet clean. ### Step 5: Commit ```bash -cd /Users/haihuang/works/go/src/github.com/kagenti/kagenti-extensions +cd /Users/haihuang/works/go/src/github.com/rossoctl/rossocortex git add authbridge/cmd/abctl/edit/configmap.go \ authbridge/cmd/abctl/edit/configmap_test.go \ authbridge/cmd/abctl/go.mod \ @@ -678,7 +678,7 @@ Expected: all 6 tests PASS, vet clean. ### Step 5: Commit ```bash -cd /Users/haihuang/works/go/src/github.com/kagenti/kagenti-extensions +cd /Users/haihuang/works/go/src/github.com/rossoctl/rossocortex git add authbridge/cmd/abctl/edit/configmap.go \ authbridge/cmd/abctl/edit/configmap_test.go git commit -s -m "feat(abctl): Add Splice and BuildManifest helpers @@ -940,7 +940,7 @@ Expected: all 9 tests pass, vet clean. ### Step 5: Commit ```bash -cd /Users/haihuang/works/go/src/github.com/kagenti/kagenti-extensions +cd /Users/haihuang/works/go/src/github.com/rossoctl/rossocortex git add authbridge/cmd/abctl/edit/configmap.go \ authbridge/cmd/abctl/edit/configmap_test.go git commit -s -m "feat(abctl): Add Fetch and Apply for the edit flow @@ -1192,7 +1192,7 @@ Expected: all 13 tests pass. ### Step 5: Commit ```bash -cd /Users/haihuang/works/go/src/github.com/kagenti/kagenti-extensions +cd /Users/haihuang/works/go/src/github.com/rossoctl/rossocortex git add authbridge/cmd/abctl/edit/diff.go \ authbridge/cmd/abctl/edit/diff_test.go git commit -s -m "feat(abctl): Add line-diff renderer for edit confirmation @@ -1444,7 +1444,7 @@ Expected: all 17 tests pass, vet clean. ### Step 5: Commit ```bash -cd /Users/haihuang/works/go/src/github.com/kagenti/kagenti-extensions +cd /Users/haihuang/works/go/src/github.com/rossoctl/rossocortex git add authbridge/cmd/abctl/edit/status.go \ authbridge/cmd/abctl/edit/status_test.go git commit -s -m "feat(abctl): Poll /reload/status to detect framework reload @@ -1550,7 +1550,7 @@ import ( "github.com/charmbracelet/lipgloss" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/edit" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/edit" ) // editPhase tracks where the edit state machine currently sits. @@ -1648,7 +1648,7 @@ Expected: 5 new tests pass, all existing TUI tests still pass. ### Step 5: Commit ```bash -cd /Users/haihuang/works/go/src/github.com/kagenti/kagenti-extensions +cd /Users/haihuang/works/go/src/github.com/rossoctl/rossocortex git add authbridge/cmd/abctl/tui/edit_overlay.go \ authbridge/cmd/abctl/tui/edit_overlay_test.go git commit -s -m "feat(abctl): Add edit overlay state + render @@ -1862,7 +1862,7 @@ Expected: all tests pass, vet clean. ### Step 5: Commit ```bash -cd /Users/haihuang/works/go/src/github.com/kagenti/kagenti-extensions +cd /Users/haihuang/works/go/src/github.com/rossoctl/rossocortex git add authbridge/cmd/abctl/edit/edit.go \ authbridge/cmd/abctl/edit/edit_test.go git commit -s -m "feat(abctl): Add tea.Cmd factories for the edit phases @@ -1910,7 +1910,7 @@ import ( tea "github.com/charmbracelet/bubbletea" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/edit" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/edit" ) const fixtureCMYAML = `apiVersion: v1 @@ -2124,7 +2124,7 @@ editRunner edit.Runner Add to the imports: ```go -"github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/edit" +"github.com/rossoctl/rossocortex/authbridge/cmd/abctl/edit" ``` Add new `tea.Msg` types near the others: @@ -2331,7 +2331,7 @@ Expected: all tests pass, vet clean, binary builds. ### Step 5: Commit ```bash -cd /Users/haihuang/works/go/src/github.com/kagenti/kagenti-extensions +cd /Users/haihuang/works/go/src/github.com/rossoctl/rossocortex git add authbridge/cmd/abctl/tui/app.go \ authbridge/cmd/abctl/tui/keys.go \ authbridge/cmd/abctl/tui/edit_e2e_test.go \ @@ -2431,7 +2431,7 @@ Confirm the new section reads cleanly. ### Step 3: Commit ```bash -cd /Users/haihuang/works/go/src/github.com/kagenti/kagenti-extensions +cd /Users/haihuang/works/go/src/github.com/rossoctl/rossocortex git add authbridge/cmd/abctl/README.md git commit -s -m "docs(abctl): Document the e keybind for pipeline editing diff --git a/authbridge/docs/superpowers/plans/2026-05-28-abctl-plugin-config.md b/authbridge/docs/superpowers/plans/2026-05-28-abctl-plugin-config.md index 5958f4536..b65e06866 100644 --- a/authbridge/docs/superpowers/plans/2026-05-28-abctl-plugin-config.md +++ b/authbridge/docs/superpowers/plans/2026-05-28-abctl-plugin-config.md @@ -974,7 +974,7 @@ import ( "strings" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/apiclient" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/apiclient" ) func TestShowPluginDetailRendersConfig(t *testing.T) { diff --git a/authbridge/docs/superpowers/plans/2026-05-28-abctl-pod-picker.md b/authbridge/docs/superpowers/plans/2026-05-28-abctl-pod-picker.md index a1e293edd..802009bfd 100644 --- a/authbridge/docs/superpowers/plans/2026-05-28-abctl-pod-picker.md +++ b/authbridge/docs/superpowers/plans/2026-05-28-abctl-pod-picker.md @@ -800,7 +800,7 @@ import ( tea "github.com/charmbracelet/bubbletea" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/cluster" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/cluster" ) // fakeLister returns a fixed []AgentNamespace. @@ -933,7 +933,7 @@ Find the `model` struct definition. Add these fields at the end (preserve existi Add the import for `cluster` to the import block: ```go -"github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/cluster" +"github.com/rossoctl/rossocortex/authbridge/cmd/abctl/cluster" ``` Add tea messages near the other tea-message types: @@ -957,7 +957,7 @@ import ( "github.com/charmbracelet/bubbles/table" tea "github.com/charmbracelet/bubbletea" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/cluster" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/cluster" ) // newNamespacesTable builds an empty namespaces picker table. @@ -1179,7 +1179,7 @@ package tui import ( "github.com/charmbracelet/bubbles/table" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/cluster" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/cluster" ) // newPodsTable builds an empty pods picker table. @@ -1684,8 +1684,8 @@ import ( "os/signal" "syscall" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/cluster" - "github.com/kagenti/kagenti-extensions/authbridge/cmd/abctl/tui" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/cluster" + "github.com/rossoctl/rossocortex/authbridge/cmd/abctl/tui" ) func main() { diff --git a/authbridge/docs/superpowers/plans/2026-06-02-credential-placeholder-swap.md b/authbridge/docs/superpowers/plans/2026-06-02-credential-placeholder-swap.md index e579ff76f..8f34714cf 100644 --- a/authbridge/docs/superpowers/plans/2026-06-02-credential-placeholder-swap.md +++ b/authbridge/docs/superpowers/plans/2026-06-02-credential-placeholder-swap.md @@ -345,8 +345,8 @@ package pipeline_test import ( "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/shared" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/shared" ) // shared.Store must satisfy pipeline.SharedStore so listeners can inject it. @@ -426,9 +426,9 @@ import ( "testing" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/placeholder" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/shared" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/placeholder" + "github.com/rossoctl/rossocortex/authbridge/authlib/shared" ) // fakeAuth lets us drive OnRequest's allow path without real JWKS. @@ -543,7 +543,7 @@ At the end of `Configure`, immediately before `return nil` (line 293), add: } ``` -Ensure `time` is imported in plugin.go (it is used elsewhere; if not, add to the import block). Add `"github.com/kagenti/kagenti-extensions/authbridge/authlib/placeholder"` and confirm `"github.com/kagenti/kagenti-extensions/authbridge/authlib/auth"` are imported (auth is already used for `p.inner`). +Ensure `time` is imported in plugin.go (it is used elsewhere; if not, add to the import block). Add `"github.com/rossoctl/rossocortex/authbridge/authlib/placeholder"` and confirm `"github.com/rossoctl/rossocortex/authbridge/authlib/auth"` are imported (auth is already used for `p.inner`). - [ ] **Step 5: Add the `mint` helper** @@ -629,9 +629,9 @@ import ( "testing" "time" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/placeholder" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/shared" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/placeholder" + "github.com/rossoctl/rossocortex/authbridge/authlib/shared" ) func resolveTestPlugin(t *testing.T, exchangeURL string) *TokenExchange { @@ -745,7 +745,7 @@ In `authlib/plugins/tokenexchange/plugin.go`, add to `tokenExchangeConfig` (afte - [ ] **Step 4: Add the resolve step to `OnRequest`** -Add the placeholder import: `"github.com/kagenti/kagenti-extensions/authbridge/authlib/placeholder"`. +Add the placeholder import: `"github.com/rossoctl/rossocortex/authbridge/authlib/placeholder"`. In `OnRequest`, replace the opening lines: @@ -791,7 +791,7 @@ func resolvePlaceholder(pctx *pipeline.Context, handle string) (string, bool) { } ``` -(`auth` is already imported — `auth.ExtractBearer` is used in the listeners and `p.inner` is `*auth.Auth`. Confirm the import is present in plugin.go; if not, add `"github.com/kagenti/kagenti-extensions/authbridge/authlib/auth"`.) +(`auth` is already imported — `auth.ExtractBearer` is used in the listeners and `p.inner` is `*auth.Auth`. Confirm the import is present in plugin.go; if not, add `"github.com/rossoctl/rossocortex/authbridge/authlib/auth"`.) - [ ] **Step 5: Run tests to verify they pass** @@ -826,7 +826,7 @@ import ( "net/http/httptest" "testing" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) // rewritePlugin sets a new Authorization on the inbound context, simulating @@ -970,7 +970,7 @@ import ( "testing" corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" - "github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline" + "github.com/rossoctl/rossocortex/authbridge/authlib/pipeline" ) type mintPlugin struct{} @@ -1088,7 +1088,7 @@ In `cmd/authbridge-proxy/main.go`, immediately after the `rpSrv, err := reversep fpSrv.Shared = sharedStore ``` -Add the import `"github.com/kagenti/kagenti-extensions/authbridge/authlib/shared"`. +Add the import `"github.com/rossoctl/rossocortex/authbridge/authlib/shared"`. - [ ] **Step 2: authbridge-lite — same injection** @@ -1121,7 +1121,7 @@ Update the call site (line ~216): grpcServers = append(grpcServers, startGRPCExtProc(inboundH, outboundH, sessions, shared.New(), cfg.Listener.ExtProcAddr)) ``` -Add the imports `"github.com/kagenti/kagenti-extensions/authbridge/authlib/shared"` and (if not present) `"github.com/kagenti/kagenti-extensions/authbridge/authlib/pipeline"`. +Add the imports `"github.com/rossoctl/rossocortex/authbridge/authlib/shared"` and (if not present) `"github.com/rossoctl/rossocortex/authbridge/authlib/pipeline"`. - [ ] **Step 4: Build everything** diff --git a/authbridge/docs/superpowers/plans/2026-06-17-authbridge-tlsbridge-phase1.md b/authbridge/docs/superpowers/plans/2026-06-17-authbridge-tlsbridge-phase1.md index a3fbf4b4b..67d5d0039 100644 --- a/authbridge/docs/superpowers/plans/2026-06-17-authbridge-tlsbridge-phase1.md +++ b/authbridge/docs/superpowers/plans/2026-06-17-authbridge-tlsbridge-phase1.md @@ -10,7 +10,7 @@ **Scope (Phase 1 is test-only):** This PR is AuthBridge-only and proves the decrypt→pipeline→re-originate loop via **in-process integration tests** (a client configured to trust the ephemeral CA). It does **not** make a real operator-deployed agent trust the CA — that is Phase 2 (operator) work. On a real cluster, a live agent's egress will safely **tunnel** (the no-broken-calls guarantee), because it does not yet trust the minted leaf. See "Phase 2 compatibility" below — Phase 1 is built so the cert-manager path (2c) drops in with a one-line `main.go` swap and no changes to the bridge core. -**Tech Stack:** Go 1.25, stdlib `crypto/tls` + `crypto/x509` (hand-rolled cert minting), `golang.org/x/net/http2` for h2. Module: `github.com/kagenti/kagenti-extensions/authbridge/authlib` (`go.mod` already has `golang.org/x/net v0.51.0` as an indirect dep — Task 5 promotes it to direct). Tests are package-internal `_test.go`, table-driven, loopback listeners; run with `go test ./...` from `authbridge/authlib`. +**Tech Stack:** Go 1.25, stdlib `crypto/tls` + `crypto/x509` (hand-rolled cert minting), `golang.org/x/net/http2` for h2. Module: `github.com/rossoctl/rossocortex/authbridge/authlib` (`go.mod` already has `golang.org/x/net v0.51.0` as an indirect dep — Task 5 promotes it to direct). Tests are package-internal `_test.go`, table-driven, loopback listeners; run with `go test ./...` from `authbridge/authlib`. **Spec:** `authbridge/docs/superpowers/specs/2026-06-12-authbridge-tlsbridge-design.md` @@ -62,7 +62,7 @@ - [ ] **Step 1: Create the implementation branch from current upstream main** ```bash -cd /Users/haihuang/works/go/src/github.com/kagenti/kagenti-extensions +cd /Users/haihuang/works/go/src/github.com/rossoctl/rossocortex git fetch upstream main git checkout -b feat/tlsbridge-phase1 upstream/main ``` @@ -1042,7 +1042,7 @@ Add the field to the `Server` struct (after `SkipHosts`): TLSBridge *tlsbridge.Engine // nil = disabled ``` -Add the import `"github.com/kagenti/kagenti-extensions/authbridge/authlib/tlsbridge"` and `"strconv"`. +Add the import `"github.com/rossoctl/rossocortex/authbridge/authlib/tlsbridge"` and `"strconv"`. Add helpers (bottom of `server.go`): diff --git a/authbridge/docs/superpowers/specs/2026-05-22-authbridge-go-spiffe-sdk-design.md b/authbridge/docs/superpowers/specs/2026-05-22-authbridge-go-spiffe-sdk-design.md index c5d5b16f9..fba9100ce 100644 --- a/authbridge/docs/superpowers/specs/2026-05-22-authbridge-go-spiffe-sdk-design.md +++ b/authbridge/docs/superpowers/specs/2026-05-22-authbridge-go-spiffe-sdk-design.md @@ -2,7 +2,7 @@ **Status:** Design — pending user review **Date:** 2026-05-22 -**Issue:** [kagenti-extensions#332](https://github.com/kagenti/kagenti-extensions/issues/332) +**Issue:** [rossocortex#332](https://github.com/rossoctl/rossocortex/issues/332) **Reference:** [klaviger's SDK usage](https://github.com/grs/klaviger/blob/main/internal/spiffe/jwt_source.go) ## Goal @@ -19,7 +19,7 @@ debugging shells) keep finding fresh files. - Operator changes (webhook, CRDs, e2e fixtures). Follow-up PR. - Helm chart changes (`spiffe-helper-config` ConfigMap, helper.conf templates). Follow-up PR. -- Backend (`kagenti/backend`) changes (DEFAULT_SPIFFE_HELPER_CONF). Follow-up. +- Backend (`rossoctl/backend`) changes (DEFAULT_SPIFFE_HELPER_CONF). Follow-up. - Implementing gRPC SDS for envoy-sidecar mode mTLS. Future PR; this design preserves the file-mirror so that work can use filesystem SDS instead. - Changing the `X509Source` / `JWTSource` interfaces consumed by `authlib/tls` @@ -110,7 +110,7 @@ just constructs an implementation that satisfies it. - `authlib/spiffe/x509source.go` (FileX509Source) + `x509source_test.go` - `authlib/plugins/tokenexchange/spiffe/file.go` (FileJWTSource) + `file_test.go` -Per kagenti CLAUDE.md "delete completely if unused" — no runtime caller, no +Per rossoctl CLAUDE.md "delete completely if unused" — no runtime caller, no need to keep dead code in-tree. ### Files modified @@ -164,7 +164,7 @@ mtls: spiffe: socket: unix:///spiffe-workload-api/spire-agent.sock # default - jwt_audience: "http://keycloak.localtest.me:8080/realms/kagenti" + jwt_audience: "http://keycloak.localtest.me:8080/realms/rossoctl" mirror_files: true # default mirror_dir: /opt # default @@ -323,7 +323,7 @@ mechanically rewritten to use a fake or the new SDK source. ### End-to-end -`kagenti/tests/e2e/token_exchange/test_token_exchange.py` does +`rossoctl/tests/e2e/token_exchange/test_token_exchange.py` does `kubectl exec ... cat /opt/jwt_svid.token`. With `mirror_files=true` default, this **continues to work** — the file still exists and contains a valid token. No e2e edits required. @@ -369,7 +369,7 @@ follow-ups. **One concrete failure mode:** chart sets `tokenexchange.identity.type: spiffe` but doesn't yet render `spiffe.jwt_audience` → authbridge fails Validate at startup. -**Mitigation:** before this PR merges, the kagenti chart PR that adds +**Mitigation:** before this PR merges, the rossoctl chart PR that adds `spiffe.jwt_audience` rendering must merge first. Realistic order: 1. Chart PR (adds `spiffe.jwt_audience` rendering, leaves @@ -396,7 +396,7 @@ the old image's loader rejects. | Repo | What | |---|---| -| `kagenti/charts/kagenti/templates/` | Add `spiffe.jwt_audience` rendering. **Must precede this PR.** Later: remove `spiffe-helper-config` ConfigMap, stop emitting old fields. | -| `kagenti/kagenti-operator` | Webhook injector: stop creating `spiffe-helper-config` Volume; surface `JWT_AUDIENCE` into authbridge YAML's `spiffe.jwt_audience`. Update e2e fixtures. | -| `kagenti/kagenti/backend` | Delete `DEFAULT_SPIFFE_HELPER_CONF`; stop creating spiffe-helper-config ConfigMap on agent runtime creation. | -| `kagenti-extensions/authbridge` (envoy-sidecar mTLS) | When envoy-sidecar mode adds mTLS, Envoy's filesystem SDS can read the same `/opt/svid*.pem` paths the mirror writes. No additional auth bridge change needed — payoff of this design's option-B choice. | +| `rossoctl/charts/rossoctl/templates/` | Add `spiffe.jwt_audience` rendering. **Must precede this PR.** Later: remove `spiffe-helper-config` ConfigMap, stop emitting old fields. | +| `rossoctl/operator` | Webhook injector: stop creating `spiffe-helper-config` Volume; surface `JWT_AUDIENCE` into authbridge YAML's `spiffe.jwt_audience`. Update e2e fixtures. | +| `rossoctl/rossoctl/backend` | Delete `DEFAULT_SPIFFE_HELPER_CONF`; stop creating spiffe-helper-config ConfigMap on agent runtime creation. | +| `rossocortex/authbridge` (envoy-sidecar mTLS) | When envoy-sidecar mode adds mTLS, Envoy's filesystem SDS can read the same `/opt/svid*.pem` paths the mirror writes. No additional auth bridge change needed — payoff of this design's option-B choice. | diff --git a/authbridge/docs/superpowers/specs/2026-06-12-authbridge-tlsbridge-design.md b/authbridge/docs/superpowers/specs/2026-06-12-authbridge-tlsbridge-design.md index 3bd21b3c0..348e459ad 100644 --- a/authbridge/docs/superpowers/specs/2026-06-12-authbridge-tlsbridge-design.md +++ b/authbridge/docs/superpowers/specs/2026-06-12-authbridge-tlsbridge-design.md @@ -2,7 +2,7 @@ **Date:** 2026-06-12 (revised after adversarial review; renamed 2026-06-17) **Status:** Converged design — ready for implementation plan. -**Repos touched:** `kagenti-extensions/AuthBridge` (proxy), `kagenti-operator` (CA coordination) +**Repos touched:** `rossocortex/AuthBridge` (proxy), `operator` (CA coordination) > **Terminology:** this feature was originally called "MITM". It is now the > **TLS bridge** — terminate one TLS connection, run the pipeline on plaintext, diff --git a/authbridge/keycloak_sync.py b/authbridge/keycloak_sync.py index e9dee9106..af5c78237 100644 --- a/authbridge/keycloak_sync.py +++ b/authbridge/keycloak_sync.py @@ -442,7 +442,7 @@ def main(): help="Path to routes.yaml (default: /etc/authproxy/routes.yaml)", ) parser.add_argument("--keycloak-url", default="http://keycloak.localtest.me:8080", help="Keycloak server URL") - parser.add_argument("--realm", default="kagenti", help="Keycloak realm (default: kagenti)") + parser.add_argument("--realm", default="rossoctl", help="Keycloak realm (default: rossoctl)") parser.add_argument("--admin-user", default="admin", help="Keycloak admin username") parser.add_argument("--admin-password", default="admin", help="Keycloak admin password") parser.add_argument("--dry-run", "-n", action="store_true", help="Show what would be done without making changes") diff --git a/authbridge/proxy-init/Makefile b/authbridge/proxy-init/Makefile index da64777ca..982410aae 100644 --- a/authbridge/proxy-init/Makefile +++ b/authbridge/proxy-init/Makefile @@ -1,6 +1,6 @@ .PHONY: docker-build-init load-image -KIND_CLUSTER_NAME ?= kagenti +KIND_CLUSTER_NAME ?= rossoctl # Container runtime — defaults to podman (the repo's primary toolchain) # but auto-falls-through to docker if podman isn't installed. Override diff --git a/authbridge/proxy-init/README.md b/authbridge/proxy-init/README.md index 88ce8ebd9..a53933d42 100644 --- a/authbridge/proxy-init/README.md +++ b/authbridge/proxy-init/README.md @@ -120,7 +120,7 @@ whichever the host kernel exposes. Override with `IPTABLES_CMD` (and ## Required Kubernetes capabilities The container needs `NET_ADMIN` and `NET_RAW` capabilities and runs as -UID 0 — but **not** privileged mode. The kagenti-operator's webhook +UID 0 — but **not** privileged mode. The operator's webhook sets up the SecurityContext correctly when injecting the init container. @@ -132,7 +132,7 @@ make load-image # load into a kind cluster ``` The image is published from CI as -`ghcr.io/kagenti/kagenti-extensions/proxy-init:` (build defined +`ghcr.io/rossoctl/rossocortex/proxy-init:` (build defined in [`.github/workflows/build.yaml`](../../.github/workflows/build.yaml)). ## Testing @@ -151,7 +151,7 @@ sudo ./test-enforce-redirect.sh ## Where it gets injected -The kagenti-operator's mutating webhook injects the proxy-init +The operator's mutating webhook injects the proxy-init container automatically: - `redirect` mode (`MODE` unset) when the resolved AuthBridge mode is diff --git a/authbridge/sparc-service/Dockerfile b/authbridge/sparc-service/Dockerfile index fa504deb7..5d348bfae 100644 --- a/authbridge/sparc-service/Dockerfile +++ b/authbridge/sparc-service/Dockerfile @@ -1,4 +1,4 @@ -# Kagenti SPARC reflection service. +# Rossoctl SPARC reflection service. # Depends on the agent-lifecycle-toolkit (ALTK) package straight from PyPI — no vendoring. FROM python:3.12-slim AS base diff --git a/authbridge/sparc-service/README.md b/authbridge/sparc-service/README.md index 547df8178..bc3323df4 100644 --- a/authbridge/sparc-service/README.md +++ b/authbridge/sparc-service/README.md @@ -1,4 +1,4 @@ -# Kagenti SPARC reflection service +# Rossoctl SPARC reflection service A thin, in-process HTTP wrapper around the **SPARC** pre-tool reflection component (`altk.pre_tool.sparc.SPARCReflectionComponent`) from the @@ -25,7 +25,7 @@ Deploy this service **once per cluster, before enabling the `sparc` plugin** on ```bash cd deploy export WX_API_KEY=... WX_PROJECT_ID=... # or PROVIDER=ollama, openai, ... -make install # → kagenti-system; published image +make install # → rossoctl-system; published image # kind dev cluster (build + load a local image first): make image install ``` @@ -147,5 +147,5 @@ SPARC_LLM_PROVIDER=ollama SPARC_MODEL=llama3.2:3b python -m sparc_service ## Build the image ```bash -docker build -t kagenti-sparc-service:latest . +docker build -t rossoctl-sparc-service:latest . ``` diff --git a/authbridge/sparc-service/deploy/Makefile b/authbridge/sparc-service/deploy/Makefile index 486a75b8a..75fea8e0d 100644 --- a/authbridge/sparc-service/deploy/Makefile +++ b/authbridge/sparc-service/deploy/Makefile @@ -16,8 +16,8 @@ .DEFAULT_GOAL := help PROVIDER ?= watsonx -NAMESPACE ?= kagenti-system -IMAGE ?= ghcr.io/kagenti/kagenti-extensions/sparc-service:latest +NAMESPACE ?= rossoctl-system +IMAGE ?= ghcr.io/rossoctl/rossocortex/sparc-service:latest TRACK ?= fast_track LLM_TIMEOUT ?= 120 PORT ?= 8090 @@ -27,7 +27,7 @@ OLLAMA_BASE_URL ?= http://host.docker.internal:11434 LLM_KWARGS_JSON ?= LLM_REGISTRY_ID ?= # Local build / kind (only used by `make image`). -KIND_CLUSTER_NAME ?= kagenti +KIND_CLUSTER_NAME ?= rossoctl KIND_NODE := $(KIND_CLUSTER_NAME)-control-plane CONTAINER_RUNTIME ?= $(shell docker info >/dev/null 2>&1 && echo docker || (podman info >/dev/null 2>&1 && echo podman) || echo docker) diff --git a/authbridge/sparc-service/deploy/README.md b/authbridge/sparc-service/deploy/README.md index b0bfc0af0..58ac8bcf0 100644 --- a/authbridge/sparc-service/deploy/README.md +++ b/authbridge/sparc-service/deploy/README.md @@ -23,14 +23,14 @@ make install PROVIDER=litellm MODEL=anthropic/claude-3-5-sonnet ANTHROPIC_API_KE `make install` creates the `sparc-service-config` ConfigMap and a `sparc-creds` Secret (from whatever provider credentials are in your environment), deploys the service into `NAMESPACE` -(default `kagenti-system`), and waits for it to become ready. Re-running it is idempotent. +(default `rossoctl-system`), and waits for it to become ready. Re-running it is idempotent. When it's up, enable the plugin on an agent — see [`docs/sparc-plugin.md`](../../docs/sparc-plugin.md#prerequisite-deploy-the-sparc-service). ## Image -The default image is `ghcr.io/kagenti/kagenti-extensions/sparc-service:latest` (published by CI). +The default image is `ghcr.io/rossoctl/rossocortex/sparc-service:latest` (published by CI). On a **kind** dev cluster, build and load a local image first: ```bash @@ -46,7 +46,7 @@ All knobs are `make` variables (mirrors of the service's [environment settings]( | Variable | Default | Notes | |---|---|---| | `PROVIDER` | `watsonx` | `watsonx` \| `ollama` \| `openai` \| `azure` \| `litellm` | -| `NAMESPACE` | `kagenti-system` | where the service is deployed | +| `NAMESPACE` | `rossoctl-system` | where the service is deployed | | `IMAGE` | ghcr `sparc-service:latest` | override for a local build or private registry | | `MODEL` | per-provider | required for `azure`/`litellm` (e.g. `azure/`) | | `TRACK` | `fast_track` | SPARC reflection track | diff --git a/authbridge/sparc-service/deploy/sparc-service.yaml b/authbridge/sparc-service/deploy/sparc-service.yaml index 3f0d53858..49822aff0 100644 --- a/authbridge/sparc-service/deploy/sparc-service.yaml +++ b/authbridge/sparc-service/deploy/sparc-service.yaml @@ -1,6 +1,6 @@ # SPARC reflection service — the backend the AuthBridge `sparc` plugin calls. # -# Deploy this ONCE per cluster (any namespace; kagenti-system by convention) +# Deploy this ONCE per cluster (any namespace; rossoctl-system by convention) # BEFORE enabling the `sparc` plugin on an agent. Agents reach it at # http://sparc-service..svc:8090/reflect. # @@ -28,7 +28,7 @@ spec: app.kubernetes.io/name: sparc-service # The service makes its own egress to the LLM provider; keep it out of # agent-side sidecar injection / ambient capture. - kagenti.io/inject: disabled + rossoctl.io/inject: disabled spec: securityContext: runAsNonRoot: true @@ -37,7 +37,7 @@ spec: type: RuntimeDefault containers: - name: sparc-service - image: ghcr.io/kagenti/kagenti-extensions/sparc-service:latest + image: ghcr.io/rossoctl/rossocortex/sparc-service:latest imagePullPolicy: IfNotPresent ports: - containerPort: 8090 diff --git a/authbridge/sparc-service/pyproject.toml b/authbridge/sparc-service/pyproject.toml index fdae7b124..4322aa1bd 100644 --- a/authbridge/sparc-service/pyproject.toml +++ b/authbridge/sparc-service/pyproject.toml @@ -3,9 +3,9 @@ requires = ["hatchling"] build-backend = "hatchling.build" [project] -name = "kagenti-sparc-service" +name = "rossoctl-sparc-service" version = "0.1.0" -description = "Kagenti SPARC reflection service — a thin in-process HTTP wrapper around the SPARC pre-tool reflection component from the agent-lifecycle-toolkit (ALTK)." +description = "Rossoctl SPARC reflection service — a thin in-process HTTP wrapper around the SPARC pre-tool reflection component from the agent-lifecycle-toolkit (ALTK)." readme = "README.md" requires-python = ">=3.10" license = { text = "Apache-2.0" } @@ -24,7 +24,7 @@ dev = [ ] [project.scripts] -kagenti-sparc-service = "sparc_service.__main__:main" +rossoctl-sparc-service = "sparc_service.__main__:main" [tool.hatch.build.targets.wheel] packages = ["sparc_service"] diff --git a/authbridge/sparc-service/sparc_service/__init__.py b/authbridge/sparc-service/sparc_service/__init__.py index afbf6b7b3..597a1b2b7 100644 --- a/authbridge/sparc-service/sparc_service/__init__.py +++ b/authbridge/sparc-service/sparc_service/__init__.py @@ -1,4 +1,4 @@ -"""Kagenti SPARC reflection service. +"""Rossoctl SPARC reflection service. A thin, in-process HTTP wrapper around the SPARC pre-tool reflection component (`altk.pre_tool.sparc.SPARCReflectionComponent`) shipped in the diff --git a/authbridge/sparc-service/sparc_service/api.py b/authbridge/sparc-service/sparc_service/api.py index 3a7552083..67df2c24d 100644 --- a/authbridge/sparc-service/sparc_service/api.py +++ b/authbridge/sparc-service/sparc_service/api.py @@ -26,7 +26,7 @@ def create_app(engine: ReflectionEngine | None = None) -> FastAPI: engine = engine or ReflectionEngine(settings) app = FastAPI( - title="Kagenti SPARC reflection service", + title="Rossoctl SPARC reflection service", version="0.1.0", summary="In-process SPARC pre-tool reflection over HTTP.", ) diff --git a/authbridge/sparc-service/sparc_service/settings.py b/authbridge/sparc-service/sparc_service/settings.py index 12023b1c4..74e76e99b 100644 --- a/authbridge/sparc-service/sparc_service/settings.py +++ b/authbridge/sparc-service/sparc_service/settings.py @@ -3,7 +3,7 @@ Configuration is intentionally read from the environment (12-factor) so the service can be tuned via a Kubernetes ConfigMap/Secret without rebuilding the image. Watsonx credentials follow the same ``WX_*`` (with ``WATSONX_*`` -fallbacks) convention used elsewhere in Kagenti. +fallbacks) convention used elsewhere in Rossoctl. """ from __future__ import annotations diff --git a/docs/README.md b/docs/README.md index 27b18c977..0220741fa 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,3 +1,3 @@ -# Kagenti-Extensions +# Rossoctl-Extensions - [AuthBridge Docs](../authbridge/README.md) diff --git a/docs/proposals/authbridge-hooks.md b/docs/proposals/authbridge-hooks.md index 3a01129f5..800cee714 100644 --- a/docs/proposals/authbridge-hooks.md +++ b/docs/proposals/authbridge-hooks.md @@ -946,7 +946,7 @@ Until then, protocol-semantic hook names are reserved (namespace `mcp.*`, `a2a.* 2. **Async fire-and-forget for audit.** Fire-and-forget hooks (I5, O6, A1) use Rust's tokio runtime for background execution. Should AuthBridge expose a Go-side async mechanism as well, or is the Rust background task system sufficient? -3. **ext_proc body auto-configuration via operator.** When a body-accessing plugin is detected, should the operator automatically reconfigure Envoy's `processing_mode`? This crosses the boundary between AuthBridge and kagenti-operator. +3. **ext_proc body auto-configuration via operator.** When a body-accessing plugin is detected, should the operator automatically reconfigure Envoy's `processing_mode`? This crosses the boundary between AuthBridge and operator. 4. **Cross-request plugin state (sessions).** CPEX's `ContextTable` is per-request. A rate-limiting plugin needs cross-request state. Should this be supported via a persistence layer on top of the context table, or should stateful plugins use external storage (Redis, etc.)? diff --git a/local-build-and-test.sh b/local-build-and-test.sh index e00a41983..9b0532290 100755 --- a/local-build-and-test.sh +++ b/local-build-and-test.sh @@ -5,12 +5,12 @@ set -euo pipefail # This script builds all necessary images locally and loads them into Kind SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -KAGENTI_DIR="${KAGENTI_DIR:-$(cd "$SCRIPT_DIR/../kagenti" 2>/dev/null && pwd || echo "")}" -if [ -z "$KAGENTI_DIR" ] || [ ! -d "$KAGENTI_DIR" ]; then - echo "ERROR: Set KAGENTI_DIR to point to your kagenti repo clone" +ROSSOCTL_DIR="${ROSSOCTL_DIR:-$(cd "$SCRIPT_DIR/../rossoctl" 2>/dev/null && pwd || echo "")}" +if [ -z "$ROSSOCTL_DIR" ] || [ ! -d "$ROSSOCTL_DIR" ]; then + echo "ERROR: Set ROSSOCTL_DIR to point to your rossoctl repo clone" exit 1 fi -CLUSTER_NAME="${CLUSTER_NAME:-kagenti-dev}" +CLUSTER_NAME="${CLUSTER_NAME:-rossoctl-dev}" # Auto-detect container runtime (Podman or Docker) # If KIND_EXPERIMENTAL_PROVIDER is set to podman, use it regardless of what's installed @@ -56,26 +56,26 @@ fi echo "✅ Found Kind cluster: ${CLUSTER_NAME}" echo "" -# Build spiffe-idp-setup (NEW - from kagenti repo) +# Build spiffe-idp-setup (NEW - from rossoctl repo) echo "==========================================" echo "Building spiffe-idp-setup" echo "==========================================" -cd "${KAGENTI_DIR}/kagenti/auth/spiffe-idp-setup" -${CONTAINER_RUNTIME} build -t ghcr.io/kagenti/kagenti/spiffe-idp-setup:local . -load_image_to_kind ghcr.io/kagenti/kagenti/spiffe-idp-setup:local +cd "${ROSSOCTL_DIR}/rossoctl/auth/spiffe-idp-setup" +${CONTAINER_RUNTIME} build -t ghcr.io/rossoctl/rossoctl/spiffe-idp-setup:local . +load_image_to_kind ghcr.io/rossoctl/rossoctl/spiffe-idp-setup:local echo "✅ Built and loaded: spiffe-idp-setup:local" echo "" # Build authbridge (proxy-sidecar combined: authbridge-proxy + spiffe-helper) # Default deployment shape — used when the workload's mode is proxy-sidecar. -# After kagenti-extensions#411 the unified binary was split into three +# After rossocortex#411 the unified binary was split into three # mode-specific binaries; each has its own Dockerfile under cmd/authbridge-*/. echo "==========================================" echo "Building authbridge (proxy-sidecar combined)" echo "==========================================" cd "${SCRIPT_DIR}/authbridge" -${CONTAINER_RUNTIME} build -f cmd/authbridge-proxy/Dockerfile -t ghcr.io/kagenti/kagenti-extensions/authbridge:local . -load_image_to_kind ghcr.io/kagenti/kagenti-extensions/authbridge:local +${CONTAINER_RUNTIME} build -f cmd/authbridge-proxy/Dockerfile -t ghcr.io/rossoctl/rossocortex/authbridge:local . +load_image_to_kind ghcr.io/rossoctl/rossocortex/authbridge:local echo "✅ Built and loaded: authbridge:local" echo "" @@ -84,8 +84,8 @@ echo "==========================================" echo "Building authbridge-envoy (envoy-sidecar combined)" echo "==========================================" cd "${SCRIPT_DIR}/authbridge" -${CONTAINER_RUNTIME} build -f cmd/authbridge-envoy/Dockerfile -t ghcr.io/kagenti/kagenti-extensions/authbridge-envoy:local . -load_image_to_kind ghcr.io/kagenti/kagenti-extensions/authbridge-envoy:local +${CONTAINER_RUNTIME} build -f cmd/authbridge-envoy/Dockerfile -t ghcr.io/rossoctl/rossocortex/authbridge-envoy:local . +load_image_to_kind ghcr.io/rossoctl/rossocortex/authbridge-envoy:local echo "✅ Built and loaded: authbridge-envoy:local" echo "" @@ -98,8 +98,8 @@ echo "==========================================" cd "${SCRIPT_DIR}/authbridge" ${CONTAINER_RUNTIME} build -f cmd/authbridge-proxy/Dockerfile \ --build-arg GO_BUILD_TAGS="exclude_plugin_a2aparser,exclude_plugin_ibac,exclude_plugin_inferenceparser,exclude_plugin_mcpparser,exclude_plugin_opa,exclude_plugin_sparc,exclude_plugin_tokenbroker" \ - -t ghcr.io/kagenti/kagenti-extensions/authbridge-lite:local . -load_image_to_kind ghcr.io/kagenti/kagenti-extensions/authbridge-lite:local + -t ghcr.io/rossoctl/rossocortex/authbridge-lite:local . +load_image_to_kind ghcr.io/rossoctl/rossocortex/authbridge-lite:local echo "✅ Built and loaded: authbridge-lite:local" echo "" @@ -108,8 +108,8 @@ echo "==========================================" echo "Building proxy-init" echo "==========================================" cd "${SCRIPT_DIR}/authbridge/proxy-init" -${CONTAINER_RUNTIME} build -f Dockerfile.init -t ghcr.io/kagenti/kagenti-extensions/proxy-init:local . -load_image_to_kind ghcr.io/kagenti/kagenti-extensions/proxy-init:local +${CONTAINER_RUNTIME} build -f Dockerfile.init -t ghcr.io/rossoctl/rossocortex/proxy-init:local . +load_image_to_kind ghcr.io/rossoctl/rossocortex/proxy-init:local echo "✅ Built and loaded: proxy-init:local" echo "" @@ -118,15 +118,15 @@ echo "✅ All images built and loaded successfully!" echo "==========================================" echo "" echo "Images loaded into cluster '${CLUSTER_NAME}':" -echo " - ghcr.io/kagenti/kagenti/spiffe-idp-setup:local" -echo " - ghcr.io/kagenti/kagenti-extensions/authbridge:local" -echo " - ghcr.io/kagenti/kagenti-extensions/authbridge-envoy:local" -echo " - ghcr.io/kagenti/kagenti-extensions/authbridge-lite:local" -echo " - ghcr.io/kagenti/kagenti-extensions/proxy-init:local" +echo " - ghcr.io/rossoctl/rossoctl/spiffe-idp-setup:local" +echo " - ghcr.io/rossoctl/rossocortex/authbridge:local" +echo " - ghcr.io/rossoctl/rossocortex/authbridge-envoy:local" +echo " - ghcr.io/rossoctl/rossocortex/authbridge-lite:local" +echo " - ghcr.io/rossoctl/rossocortex/proxy-init:local" echo "" echo "Next steps:" echo " 1. Update values files to use :local tag" -echo " 2. Run: cd ${KAGENTI_DIR} && deployments/ansible/run-install.sh --env dev" +echo " 2. Run: cd ${ROSSOCTL_DIR} && deployments/ansible/run-install.sh --env dev" echo " 3. Verify SPIRE and Keycloak are running" echo " 4. Run the AuthBridge demo" echo "" diff --git a/tests/conftest.py b/tests/conftest.py index 07ce385ef..323c79c13 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,4 +1,4 @@ -"""Shared fixtures for kagenti-extensions tests.""" +"""Shared fixtures for rossocortex tests.""" from unittest.mock import MagicMock diff --git a/verify-spire-keycloak.sh b/verify-spire-keycloak.sh index c0cac1674..7077d8ee2 100755 --- a/verify-spire-keycloak.sh +++ b/verify-spire-keycloak.sh @@ -99,19 +99,19 @@ echo "" # Check SPIFFE IdP setup job echo "6. Checking SPIFFE IdP setup job..." -if kubectl get job -n kagenti-system kagenti-spiffe-idp-setup-job &>/dev/null; then - JOB_STATUS=$(kubectl get job -n kagenti-system kagenti-spiffe-idp-setup-job -o jsonpath='{.status.conditions[?(@.type=="Complete")].status}') +if kubectl get job -n rossoctl-system rossoctl-spiffe-idp-setup-job &>/dev/null; then + JOB_STATUS=$(kubectl get job -n rossoctl-system rossoctl-spiffe-idp-setup-job -o jsonpath='{.status.conditions[?(@.type=="Complete")].status}') if [ "$JOB_STATUS" == "True" ]; then echo "✅ SPIFFE IdP setup job completed successfully" echo "" echo "Job logs:" - kubectl logs -n kagenti-system job/kagenti-spiffe-idp-setup-job --tail=20 + kubectl logs -n rossoctl-system job/rossoctl-spiffe-idp-setup-job --tail=20 else echo "⚠️ SPIFFE IdP setup job has not completed yet" - kubectl get job -n kagenti-system kagenti-spiffe-idp-setup-job + kubectl get job -n rossoctl-system rossoctl-spiffe-idp-setup-job echo "" echo "Job logs:" - kubectl logs -n kagenti-system job/kagenti-spiffe-idp-setup-job --tail=50 + kubectl logs -n rossoctl-system job/rossoctl-spiffe-idp-setup-job --tail=50 fi else echo "⚠️ SPIFFE IdP setup job not found (may not be deployed yet)" @@ -134,7 +134,7 @@ else echo "" echo "To access Keycloak Admin Console:" echo " 1. Open: http://keycloak.localtest.me:8080/admin" - echo " 2. Switch to the 'kagenti' realm" + echo " 2. Switch to the 'rossoctl' realm" echo " 3. Check Identity Providers → Should see 'spire-spiffe' (Type: SPIFFE)" echo "" fi From 28718735bd9fa3b59012981965cb8ed41b7d788c Mon Sep 17 00:00:00 2001 From: IBRAHIM IBRAHIM <66755652+Ibrahim2595@users.noreply.github.com> Date: Mon, 20 Jul 2026 10:16:14 -0400 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=90=9B=20Remove=20non-validating=20co?= =?UTF-8?q?ntext-guru=20go.sum=20placeholders?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The context-guru dependency was renamed github.com/kagenti/context-guru → github.com/rossoctl/context-guru, but the go.sum `h1:` and `/go.mod h1:` hashes were carried over byte-identical by the string replace. Go's `/go.mod` hash is computed over the go.mod contents, whose `module` line must become github.com/rossoctl/context-guru on republish — so the recorded hashes can never match and would trigger a `go mod verify` checksum-mismatch SECURITY ERROR for every consumer once the renamed dep is published. You can't produce a valid checksum for a module that doesn't exist yet, so rather than record known-wrong hashes, remove the placeholder lines from authlib, authbridge-envoy, and authbridge-proxy go.sum. `go mod tidy` regenerates real checksums once rossoctl/context-guru is published. The go.mod `require` (pseudo-version v0.0.0-20260713113308-b624f2c3d8c2, commit b624f2c3d8c2 — confirmed present in the repo) is unchanged; the build stays red on the unpublished dep (documented cross-repo sequencing) until the org move. Addresses review feedback on #678. Related to #1972 Assisted-By: Claude Opus 4.8 Signed-off-by: IBRAHIM IBRAHIM <66755652+Ibrahim2595@users.noreply.github.com> --- authbridge/authlib/go.sum | 2 -- authbridge/cmd/authbridge-envoy/go.sum | 2 -- authbridge/cmd/authbridge-proxy/go.sum | 2 -- 3 files changed, 6 deletions(-) diff --git a/authbridge/authlib/go.sum b/authbridge/authlib/go.sum index c34eec83c..eecd0a948 100644 --- a/authbridge/authlib/go.sum +++ b/authbridge/authlib/go.sum @@ -124,8 +124,6 @@ github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= -github.com/rossoctl/context-guru v0.0.0-20260713113308-b624f2c3d8c2 h1:nyu0kAd/+NlRM95IxEiRws2QyRtyyYRy8u8wjnwxn4o= -github.com/rossoctl/context-guru v0.0.0-20260713113308-b624f2c3d8c2/go.mod h1:arqPc8H+3s+XjplrD0ytgv1Zum241jvuGu3139DX6p8= github.com/klauspost/compress v1.18.6 h1:2jupLlAwFm95+YDR+NwD2MEfFO9d4z4Prjl1XXDjuao= github.com/klauspost/compress v1.18.6/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= diff --git a/authbridge/cmd/authbridge-envoy/go.sum b/authbridge/cmd/authbridge-envoy/go.sum index 1b0143674..95c7df6a4 100644 --- a/authbridge/cmd/authbridge-envoy/go.sum +++ b/authbridge/cmd/authbridge-envoy/go.sum @@ -122,8 +122,6 @@ github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= -github.com/rossoctl/context-guru v0.0.0-20260713113308-b624f2c3d8c2 h1:nyu0kAd/+NlRM95IxEiRws2QyRtyyYRy8u8wjnwxn4o= -github.com/rossoctl/context-guru v0.0.0-20260713113308-b624f2c3d8c2/go.mod h1:arqPc8H+3s+XjplrD0ytgv1Zum241jvuGu3139DX6p8= github.com/klauspost/compress v1.18.6 h1:2jupLlAwFm95+YDR+NwD2MEfFO9d4z4Prjl1XXDjuao= github.com/klauspost/compress v1.18.6/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= diff --git a/authbridge/cmd/authbridge-proxy/go.sum b/authbridge/cmd/authbridge-proxy/go.sum index c389e18e8..4f4819021 100644 --- a/authbridge/cmd/authbridge-proxy/go.sum +++ b/authbridge/cmd/authbridge-proxy/go.sum @@ -116,8 +116,6 @@ github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= -github.com/rossoctl/context-guru v0.0.0-20260713113308-b624f2c3d8c2 h1:nyu0kAd/+NlRM95IxEiRws2QyRtyyYRy8u8wjnwxn4o= -github.com/rossoctl/context-guru v0.0.0-20260713113308-b624f2c3d8c2/go.mod h1:arqPc8H+3s+XjplrD0ytgv1Zum241jvuGu3139DX6p8= github.com/klauspost/compress v1.18.6 h1:2jupLlAwFm95+YDR+NwD2MEfFO9d4z4Prjl1XXDjuao= github.com/klauspost/compress v1.18.6/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=