Security, Compliance, and Tenancy — Ghasi-SMS-Gateway
Version: 1.0 Status: Approved (initial baseline) Owner: Platform Security + Trust & Safety Last Updated: 2026-04-19 References: 01-enterprise-architecture, auth-service SERVICE_OVERVIEW, auth-service SECURITY_MODEL, compliance-engine SERVICE_OVERVIEW, 06 Traceability
Change log
- v1.0 (2026-04-19) — Initial populated baseline covering identity, tenancy, compliance layer, data protection, and regulatory posture. Supersedes the prior stub.
1. Purpose
Platform-wide security, compliance, and tenancy defaults for Ghasi-SMS-Gateway. Services inherit these and document service-specific deviations in their own docs. This document is the index of policy; detailed implementation sits in auth-service and compliance-engine.
2. Identity — multi-provider by design
| Item | Position |
|---|---|
| Canonical identity surface | auth-service (issues the platform JWT, publishes JWKS) |
| Base / default IdP | Keycloak (self-hosted in ghasi-identity namespace) |
| External tenant SSO | OIDC or SAML 2.0, brokered via Keycloak per-tenant IdP mappers |
| Legacy provider | Firebase Auth — existing tenants only; no new onboarding |
| Platform JWT | RS256, 15 min access / 30 d rotating refresh; kid rotated every 30 d |
| Provider abstraction | IdentityProvider port in auth-service; downstream services are IdP-agnostic |
| Enterprise provisioning | SCIM 2.0 inbound on auth-service |
See auth-service SERVICE_OVERVIEW §5 and SECURITY_MODEL §1.
2.1 Reserved-domain protection
Email domains corresponding to Ghasi staff (*@ghasi.io, *@ghasitech.*) cannot be claimed by any tenant IdP; attempts are rejected at broker claim time and emit auth.sso.session.failed.v1.
2.2 Break-glass access
A small number of platform-admin accounts are provisioned in Keycloak with native credentials + hardware WebAuthn. These bypass tenant IdPs and are audited separately.
3. Tenancy model
| Concern | Enforcement |
|---|---|
| Tenant scoping | tenantId on every row owned by a service; Kong injects X-Tenant-Id from the platform JWT |
| Cross-tenant access | Forbidden at the service guard layer; contract tests verify |
| Per-tenant IdP binding | auth.tenant_identity_providers table |
| Per-tenant compliance rule sets | compliance.tenant_rule_set_assignments |
| Per-tenant risk tiering | compliance.tenant_compliance_scores drives automated enforcement thresholds |
| Per-tenant DLQ quarantine | Held / blocked messages retained inside the tenant's partition of compliance.hold_queue |
4. Compliance Layer (platform-wide)
Every outbound SMS is evaluated by compliance-engine before routing. The layer is fail-closed: unavailability blocks delivery, never bypasses.
| Capability | Owner |
|---|---|
| Rule authoring + versioning | compliance-engine + admin-dashboard |
| Synchronous per-message evaluation (gRPC, P95 ≤ 500 ms) | compliance-engine |
| Hold queue + manual review | compliance-engine + admin-dashboard |
| Tenant scoring (0–100) and risk tiering | compliance-engine |
| Immutable audit log (≥ 13 months retention) | compliance-engine (compliance.audit_log, partitioned by month) |
| AI classification (local LLM + external fallback) | compliance-engine + compliance-ai |
| Tenant notification of holds/blocks | notification-service (consumer of compliance.message.*) |
See compliance-engine SERVICE_OVERVIEW.
5. Data protection
| Class | Stored at rest | In transit | Notes |
|---|---|---|---|
| Passwords | Argon2id (Keycloak-managed or native fallback) | TLS 1.2+ | Never logged; zxcvbn ≥ 3 |
| MFA secrets | KMS envelope (native) / Keycloak-managed (default) | TLS 1.2+ | — |
| SAML SP signing keys | Vault KV (KMS-wrapped) | — | Per-tenant |
| OIDC broker client secrets | Vault KV | — | Per-tenant |
| PII in compliance events | Masked in NATS payload; full content stored only in compliance.evaluation_log with 90 d retention | mTLS for gRPC | Tokenisation TBD |
| SMS content | Encrypted in orch.sms_messages column using per-tenant keys | mTLS between services | — |
6. Regulatory posture
| Regulation | Applicability | Primary controls |
|---|---|---|
| GDPR | All EU tenants / recipients | Right to erasure (auth.user.erased.v1), data residency on LLM fallback, DPIA for AI classification |
| TCPA (US) | US tenants sending to US recipients | Opt-out rule enforcement in compliance-engine, DLR-abuse detection |
| Regional telecom regulators (PTA, TRA, CRA, …) | Local SMPP operators | Per-jurisdiction rule sets, sender-ID whitelists, temporal rules |
| PCI DSS | If payment data ever traverses | Out of scope for SMS content; billing handles PCI via external PSP |
7. Secrets governance
All secrets in HashiCorp Vault per 03 Infrastructure §5. Rotations:
| Secret | Rotation cadence |
|---|---|
| Platform JWT RS256 keys | 30 d |
| Keycloak realm signing keys | 90 d |
| SAML SP keys (per tenant) | Annual or on tenant request |
| SCIM bearer tokens (per tenant) | Annual or on tenant request |
| API keys (customer-visible) | At tenant discretion; mandatory max 365 d |
| DB passwords | Dynamic (Vault short-lived) |
8. Audit
All security-relevant and compliance-relevant events are emitted to NATS and archived by analytics-service:
auth.events.*— login, IdP changes, SCIM, API-key lifecycle.compliance.audit.v1— every verdict, rule hit, score change, hold/release/reject.- Retention ≥ 13 months for compliance audit; ≥ 30 days for auth events.
9. Open Points
| ID | Question | Owner | Resolution date |
|---|---|---|---|
| SCT-001 | Final DPIA for on-prem local LLM classification in EU tenants | Security + Legal | TBD |
| SCT-002 | PII tokenisation strategy for cross-service compliance events (hash vs format-preserving) | Security | TBD |
| SCT-003 | Per-tenant data residency (separate Postgres / LLM per region) | Platform Arch | TBD |
| SCT-004 | Managed Keycloak (Red Hat SSO) vs self-hosted for regulated markets | Platform Arch | TBD |