Security & RBAC¶
Defence-in-depth at the edge, in transit, at rest, and at the query layer.
RBAC policy is centralised in core-svc.
Request flow — security layers¶
flowchart LR
IN([User request<br/>Bearer + X-Tenant-Slug])
ARM[Cloud Armor<br/>WAF · OWASP CRS · geo rules]
IAP[IAP<br/>officer-only hosts]
GW[Cloud LB · TLS 1.3 edge]
MESH[Anthos Service Mesh<br/>mTLS between services]
APP[SISS service<br/>FastAPI]
CORE[core-svc<br/>decision cache · Redis<br/>object-level policy]
GTC[GT Console<br/>module-level RBAC]
RLS[AlloyDB RLS<br/>tenant_id + department_id]
IN --> ARM --> IAP --> GW --> MESH --> APP
APP -->|ingress check| CORE
CORE -->|cache miss| GTC
GTC --> CORE
CORE --> APP
APP --> RLS
Controls by layer¶
| Layer | Control |
|---|---|
| Edge | Cloud Load Balancer + Cloud Armor (WAF, OWASP CRS, geo rules). IAP gates officer-only hosts. |
| Transport | TLS 1.3 at the edge; mTLS between services via Anthos Service Mesh (or Istio). |
| Secrets | Secret Manager only. CMEK on AlloyDB and GCS. |
| Network | Private GKE cluster, VPC Service Controls boundary around BigQuery / GCS / AlloyDB, Private Service Connect for Vertex AI. |
| Headers / sessions | Strict CSP, HSTS, SameSite=Strict cookies, 15-minute idle timeout, session rotated on privilege change. |
| VAPT | Quarterly third-party penetration tests starting at M6. |
RBAC¶
Authorization is split between the CityOS platform (coarse, module-level) and SISS (fine, object-level). See Platform integration for the full contract.
- GT Console answers "Can this user touch SISS, and in what role?" —
module-level
siss.*permissions, composed into GT Console roles, granted to users via group-mapping (GCIP claims) or tenant-domain defaults. - SISS answers "Can they touch this specific submission / sign this
specific perakuan?" — object-level policy enforced in
core-svcand at the AlloyDB query layer.
Module-level permissions (GT Console)¶
| Code | Meaning |
|---|---|
siss.access |
Baseline — can reach SISS at all |
siss.psp |
External submitter |
siss.officer |
Internal reviewer (CMU / ATD / ATL / SIRP) |
siss.officer.sign |
Authorised to issue a digital signature |
siss.admin |
Workflow config and user management within CMU tenant |
siss.auditor |
Read-only access to the audit BigQuery dataset |
The human-facing seed roles used elsewhere on this site (PSP,
CMU.Officer, CMU.Admin, ATD/ATL.Officer, SIRP.Officer, Auditor,
System.Admin) compose out of these permissions inside GT Console.
Object-level policy (SISS)¶
Enforced in core-svc and, for query-layer scoping, in AlloyDB via RLS:
- Tenant scoping —
tenant_idis part of every WHERE clause via RLS. - Department scoping — ATD / ATL officers see only submissions routed to their department (
department_idRLS). - Per-submission ownership — PSPs see only their firm's submissions (
tenant_id+submitter_idRLS). - Sign-authority gates — enforced in
signing-svcandworkflow-svc. - Step-up authentication — required for sensitive actions: digital signature, RBAC change, workflow config publish. See Signing.
Permission denial is audited
Every failed authorisation check is an audit event, not just an access log line. This lets auditors see attempts and patterns, not just successes. See Observability.