Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .claude/skills/orchestrate/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,15 @@ What was provided?

### Route logic

1. **`/orchestrate <repo-path>`** -- If the path points to a git repository, derive the target name from the directory basename. Check `/tmp/kagenti/orchestrate/<target>/` 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 <repo-path>`** -- If the path points to a git repository, derive the target name from the directory basename. Check `/tmp/rossoctl/orchestrate/<target>/` 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 <phase>`** -- Validate that `scan-report.md` and `plan.md` exist for the current target. If missing, instruct the user to run `/orchestrate <repo-path>` 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/<target>/`:
All orchestration state is persisted under `/tmp/rossoctl/orchestrate/<target>/`:

| File | Purpose |
|------|---------|
Expand Down Expand Up @@ -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 |
6 changes: 3 additions & 3 deletions .claude/skills/orchestrate:ci/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ security scanning, dependency management, and supply chain hardening.

## Prerequisites

- Plan exists at `/tmp/kagenti/orchestrate/<target>/plan.md`
- Scan report at `/tmp/kagenti/orchestrate/<target>/scan-report.md`
- Plan exists at `/tmp/rossoctl/orchestrate/<target>/plan.md`
- Scan report at `/tmp/rossoctl/orchestrate/<target>/scan-report.md`
- Target repo in `.repos/<target>/`

## Read Scan Report First
Expand Down Expand Up @@ -402,7 +402,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/<target>/phase-status.md`.
Set ci to `complete` in `/tmp/rossoctl/orchestrate/<target>/phase-status.md`.

## Related Skills

Expand Down
6 changes: 3 additions & 3 deletions .claude/skills/orchestrate:plan/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ is Phase 1 — interactive brainstorming with the developer, no PRs.
Scan report must exist:

```bash
cat /tmp/kagenti/orchestrate/<target>/scan-report.md
cat /tmp/rossoctl/orchestrate/<target>/scan-report.md
```

## Planning Process
Expand Down Expand Up @@ -78,7 +78,7 @@ Target 600-700 lines per PR. For each phase:

## Plan Output

Save to `/tmp/kagenti/orchestrate/<target>/plan.md`:
Save to `/tmp/rossoctl/orchestrate/<target>/plan.md`:

```markdown
# Enhancement Plan: <target>
Expand Down Expand Up @@ -128,7 +128,7 @@ Save to `/tmp/kagenti/orchestrate/<target>/plan.md`:
Initialize phase tracking:

```bash
cat > /tmp/kagenti/orchestrate/<target>/phase-status.md << 'EOF'
cat > /tmp/rossoctl/orchestrate/<target>/phase-status.md << 'EOF'
# Phase Status: <target>

| Phase | Status | PR | Date |
Expand Down
4 changes: 2 additions & 2 deletions .claude/skills/orchestrate:precommit/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ produces PR #1 — the foundation that validates all subsequent PRs.

## Prerequisites

- Plan exists at `/tmp/kagenti/orchestrate/<target>/plan.md`
- Plan exists at `/tmp/rossoctl/orchestrate/<target>/plan.md`
- Target repo cloned in `.repos/<target>/`

## Step 1: Detect Language
Expand Down Expand Up @@ -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/<target>/phase-status.md`:
Update `/tmp/rossoctl/orchestrate/<target>/phase-status.md`:
- Set precommit to `complete`
- Record PR number and date

Expand Down
4 changes: 2 additions & 2 deletions .claude/skills/orchestrate:review/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ submits reviews after user approval.

## Prerequisites

- `scan-report.md` and `plan.md` exist in `/tmp/kagenti/orchestrate/<target>/`
- `scan-report.md` and `plan.md` exist in `/tmp/rossoctl/orchestrate/<target>/`
- Phases 2-6 are complete (or at least the phases that were planned)
- PRs are open on the target repo

Expand Down Expand Up @@ -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/<target>/phase-status.md
sed -i '' 's/| review .*/| review | complete | -- | YYYY-MM-DD |/' /tmp/rossoctl/orchestrate/<target>/phase-status.md
```

## Related Skills
Expand Down
10 changes: 5 additions & 5 deletions .claude/skills/orchestrate:scan/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/<target>/scan-report.json` (never to
Write CVE findings to `/tmp/rossoctl/cve/<target>/scan-report.json` (never to
git-tracked files). Include a summary in the scan report.

Key areas to focus on:
Expand Down Expand Up @@ -326,10 +326,10 @@ git -C .repos/<target> remote -v

## Output Format

Save scan report to `/tmp/kagenti/orchestrate/<target>/scan-report.md`:
Save scan report to `/tmp/rossoctl/orchestrate/<target>/scan-report.md`:

```bash
mkdir -p /tmp/kagenti/orchestrate/<target>
mkdir -p /tmp/rossoctl/orchestrate/<target>
```

Report template:
Expand Down Expand Up @@ -439,7 +439,7 @@ Report template:

## Dependency Vulnerabilities (cve:scan)
- Scan method: [Trivy + LLM + WebSearch / LLM + WebSearch / LLM only]
- Full report: `/tmp/kagenti/cve/<target>/scan-report.json`
- Full report: `/tmp/rossoctl/cve/<target>/scan-report.json`

| Severity | Count |
|----------|-------|
Expand All @@ -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/<target>/scan-report.json` only.
> **Note:** CVE IDs and detailed descriptions are in `/tmp/rossoctl/cve/<target>/scan-report.json` only.
> Do NOT copy CVE IDs into git-tracked files, PRs, or issues.

## Gap Summary
Expand Down
4 changes: 2 additions & 2 deletions .claude/skills/skills:scan/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,10 +180,10 @@ Rate each skill 1-5:

### Phase 6: Generate Report

Save to `/tmp/kagenti/skills-scan/`:
Save to `/tmp/rossoctl/skills-scan/`:

```bash
mkdir -p /tmp/kagenti/skills-scan
mkdir -p /tmp/rossoctl/skills-scan
```

Output a structured report:
Expand Down
6 changes: 3 additions & 3 deletions .claude/skills/skills:validate/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,18 @@ Commands target local Kind clusters or test environments.

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/kagenti-operator-controller-manager
kubectl logs -n rossoctl-system deployment/rossoctl-operator-controller-manager
```

## BAD (chained commands won't match auto-approve patterns)

```bash
kubectl get pods -n kagenti-system && kubectl logs -n kagenti-system deployment/kagenti-operator-controller-manager
kubectl get pods -n rossoctl-system && kubectl logs -n rossoctl-system deployment/rossoctl-operator-controller-manager
```
```

Expand Down
8 changes: 4 additions & 4 deletions .claude/skills/skills:write/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/kagenti-operator-controller-manager
kubectl logs -n rossoctl-system deployment/rossoctl-operator-controller-manager
```
```

Expand All @@ -117,10 +117,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-operator/<skill-category>/` as the working directory:
Skills that download logs, artifacts, or save analysis output should use `/tmp/operator/<skill-category>/` as the working directory:

```bash
mkdir -p /tmp/kagenti-operator/rca
mkdir -p /tmp/operator/rca
```

### Update settings.json
Expand Down
2 changes: 1 addition & 1 deletion charts/operator/templates/manager/manager.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ spec:
{{- end }}
{{- if and .Values.spiffe .Values.spiffe.enabled .Values.spiffe.operatorAuth .Values.spiffe.operatorAuth.enabled }}
- name: spiffe-helper
image: ghcr.io/rossoctl/rossocortex/spiffe-helper:latest
image: ghcr.io/rossoctl/cortex/spiffe-helper:latest
imagePullPolicy: IfNotPresent
args:
- "-config"
Expand Down
8 changes: 4 additions & 4 deletions charts/operator/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -246,10 +246,10 @@ featureGates:
# proxy-sidecar / lite mode (always-on enforce-redirect egress capture).
defaults:
images:
envoyProxy: ghcr.io/rossoctl/rossocortex/authbridge-envoy:latest
authbridge: ghcr.io/rossoctl/rossocortex/authbridge:latest
authbridgeLite: ghcr.io/rossoctl/rossocortex/authbridge-lite:latest
proxyInit: ghcr.io/rossoctl/rossocortex/proxy-init:latest
envoyProxy: ghcr.io/rossoctl/cortex/authbridge-envoy:latest
authbridge: ghcr.io/rossoctl/cortex/authbridge:latest
authbridgeLite: ghcr.io/rossoctl/cortex/authbridge-lite:latest
proxyInit: ghcr.io/rossoctl/cortex/proxy-init:latest
pullPolicy: IfNotPresent

# Proxy settings
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@

**Goal:** Make the AuthBridge TLS bridge work end-to-end on operator-deployed agents — the operator provisions a per-agent cert-manager CA, mounts the signing key into the sidecar and the trust cert + trust env into the agent, and renders the `tls_bridge:` config block — so a real agent's outbound HTTPS is decrypted into the pipeline, gated behind an off-by-default `tlsBridgeMode`.

**Architecture:** A new `tlsBridgeMode: disabled|enabled` field on the `AgentRuntime` CRD, resolved CR→namespace→default exactly like `mtlsMode`. When `enabled` (and feature-gated on, and cert-manager present, and `authBridgeMode ∈ {proxy-sidecar, lite}`), a new per-agent CA reconciler creates a SelfSigned `Issuer` + a CA `Certificate` (`isCA: true`, **no Name Constraints**) → a Secret. The mutating webhook hard-mounts `tls.crt`/`tls.key` into the sidecar (mode `0440`) and `ca.crt` + trust env into the agent, and renders `tls_bridge: {mode: enabled, ca_dir: /etc/authbridge/tls-bridge-ca}` into the per-agent config (consolidated schema, rossocortex#522 — no scope/ca_source/cert-paths). The `:9094` session-API localhost-bind (it now carries decrypted bodies) already shipped authbridge-side in #522, so the operator PR carries no extensions work; raw-body redaction is a deferred follow-up.
**Architecture:** A new `tlsBridgeMode: disabled|enabled` field on the `AgentRuntime` CRD, resolved CR→namespace→default exactly like `mtlsMode`. When `enabled` (and feature-gated on, and cert-manager present, and `authBridgeMode ∈ {proxy-sidecar, lite}`), a new per-agent CA reconciler creates a SelfSigned `Issuer` + a CA `Certificate` (`isCA: true`, **no Name Constraints**) → a Secret. The mutating webhook hard-mounts `tls.crt`/`tls.key` into the sidecar (mode `0440`) and `ca.crt` + trust env into the agent, and renders `tls_bridge: {mode: enabled, ca_dir: /etc/authbridge/tls-bridge-ca}` into the per-agent config (consolidated schema, cortex#522 — no scope/ca_source/cert-paths). The `:9094` session-API localhost-bind (it now carries decrypted bodies) already shipped authbridge-side in #522, so the operator PR carries no extensions work; raw-body redaction is a deferred follow-up.

**Tech Stack:** Go 1.x (rossoctl-operator, kubebuilder/controller-runtime), cert-manager Go API `github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1` (v1.20.2, already vendored + scheme-registered), `k8s.io/utils/ptr`. Phase-1 AuthBridge code (rossocortex PR #522) is the **prerequisite** — the rendered `tls_bridge:` block is only understood by the post-#522 authbridge image.
**Tech Stack:** Go 1.x (rossoctl-operator, kubebuilder/controller-runtime), cert-manager Go API `github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1` (v1.20.2, already vendored + scheme-registered), `k8s.io/utils/ptr`. Phase-1 AuthBridge code (cortex PR #522) is the **prerequisite** — the rendered `tls_bridge:` block is only understood by the post-#522 authbridge image.

**Locked decisions (from brainstorming):**
1. CRD `tlsBridgeMode: disabled|enabled` maps 1:1 to `tls_bridge.mode`; `envoy-sidecar` + `enabled` ⇒ validating-webhook reject. (The authbridge schema was consolidated in #522: no scope/external — `enabled` intercepts all eligible on the configured ports.)
2. **Unconstrained** per-agent CA (no X.509 Name Constraints). Containment = per-agent isolation + sidecar-only `0440` key + rotation. (Avoids the cert-manager `NameConstraints` feature-gate dependency entirely.)
3. Fully **decoupled** from SPIRE/mTLS. Hard deps only: `authBridgeMode ∈ {proxy-sidecar, lite}` + cert-manager installed.
- **Cross-repo dependency for true SPIRE-free operation (added post-implementation, verified e2e):** the operator alone does not achieve this. The rossoctl chart renders an empty `spiffe: {}` into every agent's base config, and the pre-fix authbridge binary built the SPIFFE provider on mere presence of that block → `NewX509Source` blocked forever when no SPIRE socket was mounted. SPIRE-free boot therefore requires **rossocortex #523** (need-driven SPIFFE provider: build only when mTLS or a `identity.type=spiffe` plugin consumes it). On the operator side, `applyTLSBridgeMounts` now calls `ensureFSGroup` **unconditionally** (not only under `spireEnabled`) so the non-root sidecar can read the `0440` CA Secret without SPIRE — see the `0440`/`FSGroup=0` note below, which previously held only on the SPIRE path.
- **Cross-repo dependency for true SPIRE-free operation (added post-implementation, verified e2e):** the operator alone does not achieve this. The rossoctl chart renders an empty `spiffe: {}` into every agent's base config, and the pre-fix authbridge binary built the SPIFFE provider on mere presence of that block → `NewX509Source` blocked forever when no SPIRE socket was mounted. SPIRE-free boot therefore requires **cortex #523** (need-driven SPIFFE provider: build only when mTLS or a `identity.type=spiffe` plugin consumes it). On the operator side, `applyTLSBridgeMounts` now calls `ensureFSGroup` **unconditionally** (not only under `spireEnabled`) so the non-root sidecar can read the `0440` CA Secret without SPIRE — see the `0440`/`FSGroup=0` note below, which previously held only on the SPIRE path.

**Spec:** `rossocortex/authbridge/docs/superpowers/specs/2026-06-12-authbridge-tlsbridge-design.md` (Phase 2 section). **Phase 1 plan:** `rossocortex/authbridge/docs/superpowers/plans/2026-06-17-authbridge-tlsbridge-phase1.md`.
**Spec:** `cortex/authbridge/docs/superpowers/specs/2026-06-12-authbridge-tlsbridge-design.md` (Phase 2 section). **Phase 1 plan:** `cortex/authbridge/docs/superpowers/plans/2026-06-17-authbridge-tlsbridge-phase1.md`.

---

Expand Down Expand Up @@ -56,7 +56,7 @@ All operator paths under `operator/operator/` unless noted. Verified 2026-06-18.
- `cmd/main.go` — register the reconciler (gated).
- RBAC marker on the new reconciler + `config/rbac/role.yaml` + `charts/operator/templates/rbac/role.yaml`.

**rossocortex:** none required for this PR. The `:9094` localhost-bind already
**cortex:** none required for this PR. The `:9094` localhost-bind already
shipped in #522 (`config.Load` rewrites `session_api_addr` to loopback when
`tls_bridge.mode=enabled`). Raw-body redaction is a deferred follow-up, not a Phase-2 blocker.

Expand All @@ -78,7 +78,7 @@ git fetch origin main # or upstream main, per your remote
git checkout -b feat/tlsbridge-phase2 origin/main
```

(All operator work happens here. No rossocortex changes are needed — the `:9094` localhost-bind already landed in #522.)
(All operator work happens here. No cortex changes are needed — the `:9094` localhost-bind already landed in #522.)

---

Expand Down Expand Up @@ -338,7 +338,7 @@ git commit -s -m "feat(tlsbridge): reject tlsBridgeMode=enabled with envoy-sidec

This reconciler watches `AgentRuntime`. When the resolved mode is `enabled` AND the feature gate is on AND cert-manager is present, it ensures (per agent): a namespace SelfSigned `Issuer` (shared, name `authbridge-tls-bridge-selfsigned`) and a CA `Certificate` (`isCA: true`, `secretName: <agent>-tls-bridge-ca`, **no nameConstraints**) owned by the AgentRuntime. cert-manager then issues the Secret (`tls.crt`/`tls.key`/`ca.crt`). The hard pod-mount (Task 7) blocks pod start until that Secret exists — solving the ordering race.

> **Contract with authbridge `FileSource` (rossocortex#522).** The bridge's
> **Contract with authbridge `FileSource` (cortex#522).** The bridge's
> `NewFileSource` now *validates* the mounted Secret at boot and **fails loud** if the
> cert is not a CA (`IsCA=false` / missing `KeyUsageCertSign`) or if cert/key don't match.
> So the `Certificate` below MUST keep `IsCA: true` **and** `Usages` including
Expand Down Expand Up @@ -550,7 +550,7 @@ Run: `cd rossoctl-operator && go test ./internal/webhook/injector/ -run TestEnsu

```go
if tlsBridgeMode == TLSBridgeModeEnabled {
// Consolidated schema (rossocortex#522): mode + ca_dir only.
// Consolidated schema (cortex#522): mode + ca_dir only.
// ca_dir = the mounted cert-manager Secret (tls.crt/tls.key/ca.crt by
// convention). No scope/ca_source/cert+key paths.
cfg["tls_bridge"] = map[string]interface{}{
Expand Down Expand Up @@ -785,7 +785,7 @@ git commit -s -m "test(tlsbridge): e2e — operator-provisioned CA decrypts agen

The operator renders a `tls_bridge:` block only the post-#522 authbridge image understands (the `:9094` localhost-bind + `FileSource` validation are already in #522). So:

1. **rossocortex**: merge PR #522 → tag a new `v0.x.0-alpha.N` authbridge/proxy-init image.
1. **cortex**: merge PR #522 → tag a new `v0.x.0-alpha.N` authbridge/proxy-init image.
2. **rossoctl-operator**: merge this Phase-2 PR → tag `v0.x.0-alpha.M`.
3. **rossoctl**: bump the chart pins (operator image + authbridge sidecar images) to the new tags; this is where it becomes installable. Same operator→extensions→rossoctl order as the alpha.9 release.

Expand Down
4 changes: 2 additions & 2 deletions operator/docs/operator-managed-client-registration.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ That shape is intentional for this controller:
1. **Upgrade rossoctl-operator** to a version that includes the AuthBridge webhook and ClientRegistration controller.
2. **Enable the webhook** via Helm values (`webhook.enable: true`) and optionally `--enable-operator-client-registration`.
3. **Configure** `--spire-trust-domain` if agent namespaces use SPIRE.
4. **Remove the rossocortex webhook** chart dependency from the umbrella chart once the operator webhook is verified.
4. **Remove the cortex webhook** chart dependency from the umbrella chart once the operator webhook is verified.

Since both the webhook and controller ship in the same binary, there is no ordering concern between them.

Expand Down Expand Up @@ -173,7 +173,7 @@ Switching from **sidecar** to **operator** registration may change the **client

The webhook and operator now live in one repository (`rossoctl-operator`). This document is the single **source of truth** for the contract. Constants are co-located in the `internal/webhook/injector` package to avoid drift between annotation/label keys.

The webhook was previously part of `rossocortex`; migration tracking is in [rossocortex#266](https://github.com/rossoctl/rossocortex/issues/266).
The webhook was previously part of `cortex`; migration tracking is in [cortex#266](https://github.com/rossoctl/cortex/issues/266).

---

Expand Down
Loading
Loading