RPF-WP-0018 T01-T06: publish S3 posture, placement policy, quotas, ADR surface
T01 docs/tenancy-posture.md - vector set per service rather than one repo vector, with the provider-versus-consumer finding routed to net-kingdom. T02/T03/T06 docs/placement-policy.md - accepts placement ownership scoped to rule-here/number-there, records a placement owner per workload, reports the latency-critical + batch co-residency on platform-pg, marks the connection-ceiling trigger unmonitored pending railiance-telemetry, and answers the retention floor/ceiling question. T04 s3-consumer-interfaces 1.1.0 - quota disclosure per SS10.2. Surfaces that apps-pg has no backup, no resource limits and no tuned parameters. T05 docs/adr/ created with a mandatory-frontmatter convention and the first three ADRs. This repo previously held none. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
b83194741d
commit
e7e4e33bb8
9 changed files with 809 additions and 12 deletions
177
docs/tenancy-posture.md
Normal file
177
docs/tenancy-posture.md
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
# S3 tenancy posture declaration
|
||||
|
||||
Work record: `RPF-WP-0018` T01
|
||||
Declared: 2026-08-17
|
||||
Framework: `net-kingdom/canon/standards/tenancy-posture_v0.1.md` (draft-5, proposed)
|
||||
Contract version of this document: `1.0.0`
|
||||
|
||||
This is `railiance-platform`'s response to the Tenancy Posture ratification
|
||||
test (§20.2): *"Each publishes its own posture vector as part of review. The
|
||||
framework is validated by whether it can describe them accurately."*
|
||||
|
||||
It declares under §6 — **conformance is accuracy, not altitude**. Several
|
||||
levels below are `0`. None of them is an admission of weakness, and §6 is
|
||||
explicit that a declared low level is conformant while an unevidenced high
|
||||
level is not.
|
||||
|
||||
## Why this is a vector *set* and not a vector
|
||||
|
||||
§5 asks a **service** for one level per axis. `railiance-platform` is an OAS
|
||||
**layer** holding custody of several services with materially different
|
||||
postures. A single vector for the repo would be an average of things that are
|
||||
not alike, which is the inaccuracy §6 prohibits.
|
||||
|
||||
So: one vector per service, plus an explicit statement of what this repo owns
|
||||
versus what it merely holds policy for. The distinction matters because
|
||||
`RAILIANCE-WP-0012` and `RAILIANCE-WP-0015` deliberately moved the deployable
|
||||
surface to the `rapp-*` repos while custody and policy stayed here.
|
||||
|
||||
| Service | This repo's relationship | Deployable owned by |
|
||||
| --- | --- | --- |
|
||||
| `apps-pg` | **owns** — cluster CR is `helm/apps-pg-cluster.yaml` | this repo |
|
||||
| `forgejo-db` | **owns** — cluster CR is `helm/forgejo-db-cluster.yaml` | this repo |
|
||||
| `openbao` | **custody and policy**; package extracted | `rapp-openbao` |
|
||||
| `platform-pg` | **policy only**; consumer contract and grants here | `rapp-postgres` |
|
||||
| Valkey, MinIO | declared capability, no live instance | — |
|
||||
|
||||
## The vectors
|
||||
|
||||
### `apps-pg` — shared cluster for S5 application databases
|
||||
|
||||
```yaml
|
||||
tenancy:
|
||||
service: apps-pg
|
||||
role: storage-provider
|
||||
current: { I: 0, A: 0, E: 0, P: null, R: 0 }
|
||||
target: { I: 0, A: 0, E: 0, P: null, R: 2 }
|
||||
service_class: interactive
|
||||
reviewed: "2026-08-17"
|
||||
gap:
|
||||
R: "No backup is configured on this cluster at all — no barmanObjectStore,
|
||||
no retentionPolicy, no deletion path. R0 is the accurate reading and
|
||||
it is worse than it looks: R0 here means no recovery, not merely no
|
||||
erasure policy. Closing this is the highest-value item this
|
||||
declaration surfaced. Target R2 requires a backup target first."
|
||||
notes:
|
||||
- "I/A/E are 0 by construction, not by neglect. apps-pg holds no tenant
|
||||
concept, carries no tenant claim, and applies no tenant predicate. The
|
||||
tenant boundary for data on this cluster sits entirely in the consuming
|
||||
S5 application. See the provider note below."
|
||||
- "P is null rather than a number. See §P-axis note."
|
||||
```
|
||||
|
||||
### `forgejo-db` — dedicated cluster for the forge
|
||||
|
||||
```yaml
|
||||
tenancy:
|
||||
service: forgejo-db
|
||||
role: storage-provider
|
||||
current: { I: 0, A: 0, E: 0, P: null, R: 0 }
|
||||
target: { I: 0, A: 0, E: 0, P: null, R: 2 }
|
||||
service_class: interactive
|
||||
reviewed: "2026-08-17"
|
||||
gap:
|
||||
R: "Backup exists as a documented procedure (docs/forgejo-backup.md), not
|
||||
as a declared retention with a published erasure horizon. R2 needs the
|
||||
horizon published to the consumer, which is the point of the level."
|
||||
notes:
|
||||
- "Single-consumer cluster. Provides P2 to forgejo; is not itself at P2."
|
||||
```
|
||||
|
||||
### `openbao` — platform secrets service
|
||||
|
||||
```yaml
|
||||
tenancy:
|
||||
service: openbao
|
||||
role: credential-provider
|
||||
current: { I: 0, A: 2, E: 0, P: 0, R: 0 }
|
||||
target: { I: 0, A: 2, E: 0, P: 0, R: 1 }
|
||||
service_class: latency-critical
|
||||
reviewed: "2026-08-17"
|
||||
gap:
|
||||
R: "No retention position on audit device output or on KV version history.
|
||||
R1 (platform default) is reachable cheaply and is not yet declared."
|
||||
notes:
|
||||
- "A2 is claimed on the consumer boundary, not a tenant boundary: policy
|
||||
per workload path, bound once, centrally, in OpenBao's own policy
|
||||
engine. It is NOT delegated to flex-auth, so A3 is not claimed and is
|
||||
not currently a target — a PDP in the credential path would put
|
||||
flex-auth on OpenBao's availability path and OpenBao on flex-auth's."
|
||||
- "E is 0 on the TENANT axis and that number is misleading without this
|
||||
sentence: consumer separation in OpenBao is structural — a workload
|
||||
token's policy cannot address another workload's path at all, which is
|
||||
E4-shaped machinery. It scores 0 because the axis measures the tenant
|
||||
boundary and OpenBao has no tenant dimension. See the provider note."
|
||||
- "P0 is accurate and deliberate: one instance, every consumer shares it.
|
||||
Single-node rail; §17 scaling demands apply."
|
||||
```
|
||||
|
||||
### `platform-pg` — policy relationship only
|
||||
|
||||
Declared by `rapp-postgres`. This repo does not restate it. What this repo
|
||||
declares about it is in `docs/placement-policy.md`: the rule, the placement
|
||||
owner per consumer, and the triggers. The numbers — `instances: 1`,
|
||||
`max_connections: 100`, `1Gi`, `retentionPolicy: 30d` — are `rapp-postgres`'s
|
||||
cluster CR and its declaration to make.
|
||||
|
||||
## The P-axis note — why two entries are `null`
|
||||
|
||||
The P ladder describes **which substrate holds a tenant's data**, from the
|
||||
point of view of the workload whose data it is. `apps-pg` and `forgejo-db` are
|
||||
the substrate. Asking a cluster what its own placement level is has no
|
||||
well-formed answer: `apps-pg` *provides* P1 to each of its consumers, and
|
||||
`forgejo-db` *provides* P2 to forgejo, but neither *is* at a level.
|
||||
|
||||
Declaring `P: 1` for `apps-pg` would read as though the cluster had a
|
||||
placement, and a later reader would use it to argue about isolation. `null`
|
||||
plus the provider statement is the accurate form. This is routed as a finding.
|
||||
|
||||
## Finding routed to `net-kingdom`
|
||||
|
||||
**The five ladders describe a consumer of storage. They do not describe a
|
||||
provider of it.**
|
||||
|
||||
Every service above scores at or near zero on I, A and E, and in each case for
|
||||
the same structural reason rather than for a weakness: a storage or credential
|
||||
platform has no tenant dimension of its own. It is exactly as strong or weak as
|
||||
its consumers make it. The framework anticipates this in §3.3 and in the
|
||||
"newly absorbed repo" example, but the vector shape gives a provider no way to
|
||||
say the useful thing, which is not *what level am I at* but **what level do I
|
||||
make reachable for the workloads I hold**.
|
||||
|
||||
The concrete case is the `openbao` E line. `E: 0` is literally correct and
|
||||
actively misleading — the mechanism in place is credential-scoped structural
|
||||
separation, the same machinery E4 describes, pointed at a consumer boundary
|
||||
rather than a tenant one. A reader scanning a table of E values would rank
|
||||
OpenBao below a service doing per-query filtering in application code, which
|
||||
inverts the actual security position.
|
||||
|
||||
**Proposed amendment, offered as the first correction from review rather than
|
||||
from research (§Status observes that every correction so far came from research
|
||||
or relocation):** add a **provider declaration** beside the posture vector — a
|
||||
platform service states, per axis, the maximum level it makes reachable and
|
||||
what the consumer must do to reach it. For `apps-pg` that is: E4 unreachable
|
||||
(shared credential per consumer, no per-tenant credential), E3 reachable once
|
||||
the GUC contract exists, R2 blocked on a backup target. That is the sentence a
|
||||
consumer actually needs, and no arrangement of the five consumer ladders
|
||||
produces it.
|
||||
|
||||
This is offered as an addition, not a replacement. The consumer vector is
|
||||
right for consumers, and this repo is not asking for the ladders to be
|
||||
renumbered.
|
||||
|
||||
## What this repo accepts
|
||||
|
||||
- The P0–P4 ladder as written, by reference. It describes our estate correctly.
|
||||
- §8.1's monitoring obligation, with the deferrals stated in
|
||||
`docs/placement-policy.md` rather than silently.
|
||||
- §9.1 — no static long-lived database credentials above E0. Already how the
|
||||
credential broker works; no change needed.
|
||||
- §10.2 — quota disclosure. Landed in `docs/s3-consumer-interfaces.md` 1.1.0.
|
||||
- §6 — accuracy over altitude, which is why this document declares four zeros.
|
||||
|
||||
## Review interval
|
||||
|
||||
Six months, or on any of: a service moving placement level, a backup target
|
||||
becoming available, or the framework reaching `accepted`. Next review due
|
||||
**2027-02-17**.
|
||||
Loading…
Add table
Add a link
Reference in a new issue