diff --git a/WORK-RECORDS.md b/WORK-RECORDS.md index cbbe3f2..83dd53b 100644 --- a/WORK-RECORDS.md +++ b/WORK-RECORDS.md @@ -36,6 +36,7 @@ | task | QONTO-WP-0004-T02 | done | — | workplans/QONTO-WP-0004-security-hardening-and-scale-to-zero.md | | task | QONTO-WP-0004-T03 | done | — | workplans/QONTO-WP-0004-security-hardening-and-scale-to-zero.md | | task | QONTO-WP-0004-T04 | done | — | workplans/QONTO-WP-0004-security-hardening-and-scale-to-zero.md | -| task | QONTO-WP-0004-T05 | todo | — | workplans/QONTO-WP-0004-security-hardening-and-scale-to-zero.md | +| task | QONTO-WP-0004-T05 | done | — | workplans/QONTO-WP-0004-security-hardening-and-scale-to-zero.md | | task | QONTO-WP-0004-T06 | done | — | workplans/QONTO-WP-0004-security-hardening-and-scale-to-zero.md | | task | QONTO-WP-0004-T07 | todo | — | workplans/QONTO-WP-0004-security-hardening-and-scale-to-zero.md | +| task | QONTO-WP-0004-T08 | done | — | workplans/QONTO-WP-0004-security-hardening-and-scale-to-zero.md | diff --git a/docs/knative-runtime-and-rapp-handoff.md b/docs/knative-runtime-and-rapp-handoff.md new file mode 100644 index 0000000..1053c42 --- /dev/null +++ b/docs/knative-runtime-and-rapp-handoff.md @@ -0,0 +1,78 @@ +# Knative Runtime And `rapp-qonto` Handoff + +Date: 2026-07-26 + +## Ownership Boundary + +`qonto-assistant` keeps: + +- Qonto API domain behavior +- default-deny, no-spend/no-volume-cost policy +- tenant and actor authorization integration +- application audit events and deny-escalation behavior +- request idempotency behavior for financial operations +- application health semantics + +`rapp-qonto` receives: + +- runtime image and configuration binding +- Knative Service and rail-binding manifests +- service account and secret references +- workload-specific network policy +- rollout, smoke, rollback, and revocation checks +- measured cold-start and scale-down evidence + +`rail-knative` owns: + +- request activation and buffering +- Knative revisions and traffic routing +- scale-to-zero, minimum scale, concurrency, and autoscaling semantics +- bounded cold-start behavior +- rail-specific revision rollback + +The current `deploy/k8s/qonto-assistant/` tree and `railiance/app.toml` are +migration input. They must not continue growing as an unreviewed parallel +production target. + +## Application-Side Runtime Contract + +- Caller authentication and coarse authorization happen before activation + whenever the entry architecture permits it. +- The raw application port is never publicly exposed. +- Workload readiness must include policy and dependency readiness, not merely a + listening socket. +- The runtime fails closed when identity, authorization, or the OpenBao + credential lane is unavailable. +- Financial requests carry an idempotency key across cold start, retry, and + reconnect. +- A caller timeout does not assert that an upstream financial operation was + never attempted. +- Application audit context survives activation and upstream failure. + +## Identity And Credential Boundary + +Steady-state names target the package: + +- service account and workload principal: `rapp-qonto` +- OpenBao workload role: `rapp-qonto` +- caller client: `rapp-qonto-client` +- bank credential reference: `tenants/binky/qonto-api` + +Any role named for `qonto-assistant` is a time-bounded migration bridge. +Secret values never appear in manifests, workplans, logs, State Hub, or agent +output. Credential planning uses `warden plan`; use uses sanctioned execution, +file-output, or wrapped transports. + +## Evidence Required Before Production Approval + +- measured cold start, request timeout, concurrency, and idle scale-down +- unauthenticated, wrong-tenant, and denied-capability negative tests +- retry/idempotency test across activation +- positive and negative OpenBao access +- Qonto-only egress enforcement or a recorded compensating exception +- audit delivery and credential revocation +- previous-revision rollback +- failure behavior for identity, authorization, OpenBao, and Qonto outages + +Direct Kubernetes deployment is an exceptional, expiring fallback rather than +a parallel steady state. diff --git a/workplans/QONTO-WP-0004-security-hardening-and-scale-to-zero.md b/workplans/QONTO-WP-0004-security-hardening-and-scale-to-zero.md index ec7a2a0..c20635f 100644 --- a/workplans/QONTO-WP-0004-security-hardening-and-scale-to-zero.md +++ b/workplans/QONTO-WP-0004-security-hardening-and-scale-to-zero.md @@ -1,24 +1,33 @@ --- id: QONTO-WP-0004 type: workplan -title: "Security hardening and scale-to-zero facade for internet exposure" +title: "Security hardening and Knative runtime path for internet exposure" domain: infotech repo: qonto-assistant status: active owner: claude topic_slug: the-custodian created: "2026-07-23" -updated: "2026-07-23" +updated: "2026-07-26" state_hub_workstream_id: "81a476ac-06d5-4e98-a2ed-1518b16863aa" --- -# Security hardening and scale-to-zero facade for internet exposure +# Security hardening and Knative runtime path for internet exposure Implements `docs/SecurityPractice.md`, written ahead of deploying -`qonto-assistant` to `railiance01`. This is the first fleet service that -must be reachable by clients outside the cluster (laptop-based agent -harness sessions) while holding a real company bank credential — a risk -class above every other agent-facing service shipped so far. +`qonto-assistant` to the Railiance runtime fleet. This is the first fleet +service that must be reachable by clients outside the cluster +(laptop-based agent harness sessions) while holding a real company bank +credential — a risk class above every other agent-facing service shipped so +far. + +The intended runtime direction is now explicit: use `reef-railiance`, +establish a new `rail-knative`, and dynamically run a future `rapp-qonto` +package on that rail. This repo remains the current ownership home for the +Qonto domain code and the place where the security contract is first made +concrete, but the remaining deployment-oriented work in this plan should +feed that repo-family path rather than extend a permanent direct +`qonto-assistant` deployment target. Some of this workplan's scope depends on systems this repo does not own (`key-cape`, `flex-auth`, `tenant-engine`, Railiance placement). Those @@ -26,6 +35,13 @@ dependencies are tracked explicitly per task rather than assumed away; the `kings-guard`-owned portion is tracked as a separate intake against `KG-WP-0002`, not duplicated here. +As of Sunday, July 26, 2026, the cross-repo framework direction for that path +is tracked in +`railiance-master/workplans/RAILIANCE-WP-0019-knative-qonto-runtime-on-reef-railiance.md`. +Tasks already marked `done` below remain valid as ownership-repo hardening and +migration input; the remaining open tasks are now about handing the runtime +path into `reef-railiance`, `rail-knative`, and `rapp-qonto`. + ## Task: Security Genome record and audit-stream review ```task @@ -136,36 +152,45 @@ pass) and a real `tenant-engine` instance seeded with a `VEN` grant for both live processes over real HTTP — `allow` for the correct tenant, `live_authz_denied` for a mismatched one. 28 new unit tests. -## Task: Facade / scale-to-zero activator — design and reference implementation +## Task: Define the `rail-knative` internet-facing runtime contract ```task id: QONTO-WP-0004-T05 -status: todo +status: done priority: high state_hub_task_id: "e8a87292-488d-4871-be3e-59a5b6a38694" ``` -Per `docs/SecurityPractice.md` §2/§6: a thin, always-on facade is the only -internet-facing component. It authenticates (key-cape) and authorizes -(flex-auth pre-check) *before* waking the real service, then scales the -backend `Deployment` 0→1, waits on `/v1/health`, proxies through, and scales -back to 0 after an idle timeout. `qonto-assistant`'s raw REST/MCP port must -never be bound to a publicly-reachable address in any deployment. +Per `docs/SecurityPractice.md` §2/§6, the internet-facing wake path must +authenticate and authorize *before* waking the real service, and the backend +must still scale back to zero when idle. Under the new framework direction, +this repo should no longer assume a custom in-repo facade or a permanent direct +`Deployment` target. The default plan is now a new `rail-knative` hosted by +`reef-railiance`, with this repo describing the app-side contract that rail +must satisfy. -Check whether the target `railiance01` cluster already runs Knative Serving -before building a custom activator — if it does, this task becomes -integration (Knative Service manifest + autoscaling annotations) rather -than new code. If not, scope a minimal reference implementation (one -Service, one Deployment, one wake/idle controller) sized to this repo's -narrow surface, not a general-purpose PaaS. +This task should define, from `qonto-assistant`'s point of view: -**Depends on:** a decision on where this component lives (this repo, -Railiance, or a new dedicated repo) and Railiance cluster capabilities -(Knative or not) — flag both as open questions rather than assuming. +- the pre-wake authn/authz behavior the rail must guarantee +- the cold-start and idle-scale semantics the package path depends on +- which behavior belongs in `rail-knative` versus the future `rapp-qonto` + package versus this ownership repo +- which parts of `docs/SecurityPractice.md` need rewriting now that the target + runtime path is explicit -Done when: an unauthenticated request never triggers a backend wake; an -authenticated+authorized request gets proxied through after a bounded -cold-start; the backend scales back to 0 after the configured idle window. +**Depends on:** `RAILIANCE-WP-0019` defining the cross-repo architecture +boundary, plus the future `rail-knative` bootstrap work that will follow from +it. + +Done when: the required runtime contract is written clearly enough that future +`rail-knative` and `rapp-qonto` implementation work can start without +reopening the security model, and no new direct-deployment assumption is left +as the default target. + +**2026-07-26:** Added `docs/knative-runtime-and-rapp-handoff.md`. It defines +pre-wake controls, cold-start/idempotency/failure behavior, raw-port exposure, +identity and credential boundaries, and the evidence required before +production approval. ## Task: Isolation placement request to Railiance @@ -202,6 +227,44 @@ tier (I1 vs I2) is Railiance's scheduling call once the manifests are reviewed; whether the facade (T05) co-locates in this namespace is assumed in `networkpolicy.yaml` but not yet decided. +**2026-07-26 direction update:** this direct Kubernetes placement package now +serves as migration input and isolation evidence rather than the intended final +runtime topology. Future implementation should treat these manifests, the CCR, +and the staged-promotion contract as baseline material to be re-homed into the +`reef-railiance` + `rail-knative` + `rapp-qonto` path, not as the long-term +deployment target of this repo. + +## Task: Plan the `rapp-qonto` extraction and runtime handoff + +```task +id: QONTO-WP-0004-T08 +status: done +priority: high +state_hub_task_id: "e265cce1-df09-48ca-a0fd-f38897c44b4c" +``` + +Define how the current `qonto-assistant` deployment-oriented material hands off +into a future `rapp-qonto` package repo while preserving this repo as the +ownership home for the Qonto domain logic. + +At minimum, this task must name: + +- what stays in `qonto-assistant` +- what becomes package/runtime content in `rapp-qonto` +- how `KEY-WP-0004`'s workload-identity lane and the OpenBao secret lane bind + to the future runtime principal +- which current files are migration input only and must stop growing in place + +Done when: the extraction and handoff boundary is written; the dependency on +`RAILIANCE-WP-0019` is explicit; and no new direct +`deploy/k8s/qonto-assistant` implementation starts without an explicit +exception note. + +**2026-07-26:** The handoff document now assigns domain behavior and application +policy to this repo, package/runtime assets to `rapp-qonto`, and generic +activation/revision behavior to `rail-knative`. Existing direct Kubernetes +assets are explicitly migration input. + ## Task: Closure review ```task @@ -211,6 +274,7 @@ priority: low state_hub_task_id: "2a2da206-d182-4a72-aea4-56e58ae74c76" ``` -Close when T03–T06 land or are explicitly deferred with a recorded reason. -T01/T02 already shipped without waiting on external dependencies. Run +Close when T03–T06 and T08 land or are explicitly deferred with a recorded +reason. T01/T02 already shipped without waiting on external dependencies, and +T06 now counts as migration input rather than the final runtime shape. Run `statehub fix-consistency`.