Skip to main content

regulator-portal-service — Domain Model

Version: 1.0 Status: Draft Owner: Regulator-facing + Legal Last Updated: 2026-04-21 Companion: SERVICE_OVERVIEW · APPLICATION_LOGIC · API_CONTRACTS · DATA_MODEL · EVENT_SCHEMAS · SECURITY_MODEL


1. Bounded Context

Regulatory & Lawful-Intercept Interface. The regulator-portal-service owns the ATRA-facing and external-auditor-facing surface of the platform: Lawful Intercept (LI) request workflow per ETSI TS 102 232, citizen-complaint ingest, scheduled and ad-hoc regulator reports, SIEM forwarding, and periodic compliance attestations (ISO 27001 / SOC 2 Type II / GSMA AA.18).

Inside the boundary:

  • RegulatorUser, AuditorUser identities (national-PKI-mapped, mTLS-authenticated — no passwords)
  • LiRequest, LiAuditEntry (ETSI TS 102 232 IRI/CC/FULL) with dual-control state machine
  • Complaint (ATRA-forwarded citizen complaint) + triage record
  • ReportJob, GeneratedReport (signed PDF artifacts) and ScheduledReport definitions
  • AttestationControl catalog, AttestationEvidence freshness, AttestationBundle annual packages
  • SiemDestination (Splunk HEC / Logstash / QRadar LEEF) + SiemDeliveryLog
  • AuditorAccessGrant (time-boxed, mTLS via auditor PKI)

Outside the boundary (read-through only — read-only against upstream):

  • Audit content lives in compliance-engine (compliance.audit.v1, compliance.audit_log)
  • Consent evidence lives in consent-ledger-service (consent.granted.v1, consent.revoked.v1)
  • Sender-ID registry state lives in sender-id-registry-service
  • CDR submission state lives in cdr-mediation-service
  • Historical ClickHouse queries served by analytics-service
  • Actual traffic interception is performed by MNOs / cdr-mediation-service — regulator-portal only orchestrates the workflow

Per ADR-0004 §3, regulator-portal-service is a distinct bounded context; it never mutates upstream data. It assembles, signs, and serves.


2. Aggregates

2.1 RegulatorUser

Identity of an authenticated ATRA officer. Mapped from mTLS client-certificate subject DN (CN, O, OU, SERIALNUMBER).

FieldTypeNotes
userIdUUIDv4Platform identity
certSubjectDnstringRFC 4514 canonical DN; used as stable mapping key
certFingerprintSha256bytes(32)Verified at every handshake
issuerDnstringMust match one of the national-PKI trusted issuers
orgNamestringTypically ATRA or accredited delegated body
roleRegulatorRole enumregulator-read · regulator-li · regulator-auditor · external-auditor
allowedRegionsstring[]ISO 3166-2 subdivisions (e.g. AF-KAB)
statusUserStatusACTIVE · SUSPENDED · REVOKED
createdAt, lastLoginAt, revokedAtInstant

Invariants

  • certSubjectDn + issuerDn form a unique key (one identity per issued cert).
  • role = regulator-li requires dualControl = true on all LI transitions the user initiates.
  • status = REVOKED is terminal; CRL/OCSP revocation cascades here automatically (see SECURITY_MODEL §1.1).
  • No password, API key, or shared secret is ever associated with a RegulatorUser.

2.2 AuditorUser

Special case of a regulator-like identity for a third-party external auditor (e.g., an ISO 27001 or SOC 2 audit firm). mTLS via the auditor's own PKI; separate trust anchor from national PKI.

FieldTypeNotes
auditorIdUUIDv4
firmNamestringe.g. BigFour LLP
certSubjectDn, certFingerprintSha256, issuerDnas aboveIssuer must be in auditor_ca_trust_store
grantedFrameworksComplianceFramework[]Per-engagement scope (ISO 27001 / SOC 2 / GSMA AA.18)
accessGrantedAt, accessExpiresAtInstantTime-boxed; default 30 days (extendable by CISO + Legal)
grantedByuserIdPlatform admin who issued the grant

Invariants

  • accessExpiresAt is load-bearing — backend enforces TTL independently of JWT exp, so a stolen cert cannot outlive the grant.
  • An auditor user is read-only; all state-changing endpoints return 403 INSUFFICIENT_SCOPE.
  • Auditor reads themselves are audit-logged (meta-audit — the audit trail records who inspected it).

2.3 LiRequest

A lawful intercept request submitted by an authorised ATRA LI officer per ETSI TS 102 232-1/-2/-3 (IRI = intercept-related information; CC = communication content; FULL = both).

FieldTypeNotes
liRequestIdUUIDv4 (externally li_…)
regulatorUserIdUUIDv4Submitter
targetMsisdnE.164Single target per request (ETSI alignment)
dateRangeFrom, dateRangeToInstantInclusive window
scopeLiScope VOIRI · CC · FULL
legalRefstringCourt order reference / warrant number
signedWarrantHashbytes(32)SHA-256 of the signed PDF warrant; compared against uploaded document
warrantObjectRefstrings3://ghasi-regulator/li/warrants/{liRequestId}.pdf (object-lock 7y)
stateLiState VORECEIVED → ACK → IN_PROGRESS → DELIVERED → CLOSED (terminal) or REJECTED (terminal)
ackBy, inProgressBy, deliverBy, closeByInstantPer-state SLA deadlines
initiator, approveruserIdDual-control pair (see invariants)
deliveryPackageRefstring | nulls3://ghasi-regulator/li/deliveries/{liRequestId}/
deliverySftpReceiptAtInstant | nullConfirmed regulator receipt
createdAt, updatedAtInstant

Invariants

  • Dual-control. Every state transition requires both initiator (Ghasi Legal) and approver (Ghasi Security) to co-sign. Same user cannot fill both roles. Persisted atomically via BEGIN; SELECT FOR UPDATE; INSERT INTO li_audit; UPDATE li_requests; COMMIT;.
  • Append-only audit. LiAuditEntry rows are Postgres-rule protected against UPDATE/DELETE (see DATA_MODEL §3).
  • SLA hard-coded. ackBy = createdAt + 1h; inProgressBy = createdAt + 4h; deliverBy = createdAt + 18h; alert fires 15 min before each deadline.
  • State monotonicity. Transitions only advance (RECEIVED → ACK → IN_PROGRESS → DELIVERED → CLOSED). REJECTED reachable only from RECEIVED or ACK. REJECTED and CLOSED are terminal.
  • Warrant integrity. signedWarrantHash MUST equal SHA-256 of the uploaded PDF at ingest; mismatch → 422 and no row created.
  • Cert-revocation cascade. If regulatorUserId.status → REVOKED during an active workflow, state freezes and an URGENT alert fires; see FAILURE_MODES §FM-12.

2.4 LiAuditEntry

Append-only state-transition log. One row per transition; one row per user action within a workflow.

FieldNotes
auditIdUUIDv4
liRequestIdFK → LiRequest
fromState, toStateLiState
actionSUBMIT · ACK · START · DELIVER · CLOSE · REJECT · NOTE
initiator, approveruserId (both NOT NULL except for NOTE)
rationalestring (required on REJECT)
hashPrev, hashSelfbytes(32)
occurredAtInstant

2.5 Complaint

Citizen complaint forwarded by ATRA. Regulator-portal-service does not resolve complaints itself — it ingests, routes to admin-dashboard workbench, tracks SLA, and reports resolution back.

FieldNotes
complaintIdUUIDv4 (externally comp_…)
regulatorRefstring
citizenMsisdnMaskedstring
complaintTypeenum
summarystring (≤ 4000 chars)
receivedAtInstant
stateComplaintState
slaDueAtInstant
resolverTenantIdUUID | null
resolutionSummarystring | null
triageAiCategorystring | null

Invariants

  • slaDueAt = receivedAt + 5 business days (business-day calendar scoped to Afghanistan working week).
  • resolutionSummary is mandatory when state = RESOLVED or state = CLOSED.
  • Citizen MSISDN is never returned to anyone except platform.compliance.admin and the assigned resolver's tenant admin; citizen_msisdn column is encrypted per SECURITY_MODEL §3.

2.6 ScheduledReport and ReportJob

ScheduledReport defines the recurring contract (cron, type, recipients). ReportJob is one execution.

ScheduledReport FieldNotes
scheduledReportIdUUIDv4
reportTypeReportType VO: DAILY_CDR_STATUS · MONTHLY_COMPLIANCE_SUMMARY · QUARTERLY_PLATFORM_HEALTH · AD_HOC
cronExprCRON, timezone Asia/Kabul
recipientEmailsemail[]
enabledbool
lastRunAt, lastStatusInstant, PENDING/RUNNING/READY/FAILED
ReportJob FieldNotes
reportJobIdUUIDv4 (externally rpt_…)
scheduledReportIdFK or null for ad-hoc
filtersJSONB
statusReportStatus: PENDING · RUNNING · READY · FAILED
outputRefs3://ghasi-regulator/reports/{yyyy}/{mm}/{reportJobId}.pdf
signatureRefPKCS#7 detached signature alongside output
signingKeyRefVault path for HSM-bound regulator-reports key
requestedBy, requestedAt, completedAt

Invariants

  • Every READY report has a non-null signatureRef; a report without a signature is not downloadable.
  • outputRef and signatureRef are stored under object-lock retention = 7 years (regulatory evidence).
  • SLA: hot-window ad-hoc ≤ 30 min; cold-window (S3 Glacier restore) ≤ 24 h.

2.7 AttestationControl, AttestationEvidence, AttestationBundle

Catalog of compliance-framework controls and their evidence freshness.

AttestationControl FieldNotes
frameworkComplianceFramework VO: ISO_27001 · ISO_27017 · ISO_27018 · SOC2_TYPE_II · GSMA_AA_18
controlIde.g. A.12.4.1 for ISO 27001 (Event logging)
title, descriptionControl text
ownerServicee.g. compliance-engine, auth-service, infra
evidenceTypeAUTO_SBOM · AUTO_CI_RESULT · AUTO_ACCESS_REVIEW · AUTO_IMAGE_SIGNATURE · MANUAL_UPLOAD
AttestationEvidence FieldNotes
evidenceIdUUIDv4
framework, controlIdFK
evidenceRefs3://ghasi-regulator/evidence/{framework}/{controlId}/{hash}
manifestHashSha256bytes(32)
statusEvidenceStatus VO: CURRENT · STALE · MISSING
lastReviewAt, nextReviewDueAtInstant

Invariants

  • status = STALE iff lastReviewAt + 60 days < now().
  • status = MISSING iff no evidence row exists for that (framework, controlId).
  • Evidence files are immutable once referenced by a generated AttestationBundle.
AttestationBundle FieldNotes
bundleIdUUIDv4
framework, yearComposite natural key
bundleRefs3://ghasi-regulator/bundles/{framework}/{year}/bundle.zip (object-lock permanent)
signatureRefPKCS#7 detached (attestation-bundle signing key, HSM)
controlMatrixRef, execSummaryRefSub-artifacts inside the ZIP
generatedAt, generatedBy

2.8 SiemDestination and SiemDeliveryLog

SiemDestination FieldNotes
destinationIdUUIDv4
namee.g. ATRA-Splunk-Prod, Ghasi-QRadar-SOC
kindSPLUNK_HEC · LOGSTASH_HTTP · QRADAR_SYSLOG
endpointUrlHTTPS URL or syslog://host:port
formatCEF · LEEF · RAW_JSON
authRefVault path to credential (HEC token / mTLS cert / syslog key)
filterJSONB
enabledbool
SiemDeliveryLog FieldNotes
logIdUUIDv4
destinationIdFK
eventIdMatches NATS eventId
subjectNATS subject
statusACKED · RETRYING · DEADLETTERED
attemptsint
lastErrstring | null
ackedAtInstant | null

Invariants

  • Delivery is at-least-once with destination ACK. An event is only ACKED after the destination returns 2xx (HEC), a syslog-relay-ACK, or a Logstash ingest-ack.
  • Disk-WAL kicks in when NATS lag exceeds 1 h; see FAILURE_MODES §FM-02.

3. Value Objects

VOShapeInvariants
LiScopeIRI | CC | FULLPer ETSI TS 102 232
LiStateRECEIVED | ACK | IN_PROGRESS | DELIVERED | CLOSED | REJECTEDMonotonic except REJECTED; dual-control required
ComplaintStateRECEIVED | TRIAGED | ASSIGNED | RESOLVED | CLOSED | REJECTED5-business-day SLA
ReportTypeDAILY_CDR_STATUS | MONTHLY_COMPLIANCE_SUMMARY | QUARTERLY_PLATFORM_HEALTH | AD_HOCDetermines filter schema
ReportStatusPENDING | RUNNING | READY | FAILEDREADY requires signature
ComplianceFrameworkISO_27001 | ISO_27017 | ISO_27018 | SOC2_TYPE_II | GSMA_AA_18
EvidenceStatusCURRENT | STALE | MISSINGDerived from lastReviewAt
RegulatorRoleregulator-read | regulator-li | regulator-auditor | external-auditorScope-bound
UserStatusACTIVE | SUSPENDED | REVOKEDCRL/OCSP-driven
SiemFormatCEF | LEEF | RAW_JSONCEF per ArcSight spec; LEEF per QRadar spec

4. Domain Events (produced)

Full payloads in EVENT_SCHEMAS.md.

EventTrigger
regulator.li.received.v1LI request submitted
regulator.li.transitioned.v1Any LI state advance
regulator.li.delivered.v1LI package SFTP receipt confirmed
regulator.complaint.received.v1New complaint ingested
regulator.complaint.resolved.v1Resolution written back
regulator.report.submitted.v1Report job requested
regulator.report.acked.v1Regulator acknowledges download
regulator.report.rejected.v1Regulator raises integrity issue
regulator.siem.forwarded.v1Per-destination delivery ACK observed
regulator.attestation.evidence.collected.v1Auto-collection cron completed
regulator.attestation.bundle.generated.v1Annual bundle signed and stored
regulator.auditor.access.granted.v1 / .revoked.v1Auditor grant change

Consumed events are listed in EVENT_SCHEMAS.md §3.


5. Global Invariants

  • Read-only against upstream. regulator-portal-service never mutates any table owned by another service. Reports and deliveries are assembled by read-through gRPC/REST.
  • mTLS-only. No endpoint is reachable with password, API key, or bearer token for regulator or auditor identities. Internal admin APIs use the platform JWT via Kong.
  • CRL + OCSP enforced at every handshake. Stapled OCSP (RFC 6066) preferred; CRL fallback on OCSP outage. Hard-fail on no staple in regulator cert (soft-fail tolerated for auditor cert with Legal approval).
  • Signed reports. Every downloadable artifact (report, LI delivery, attestation bundle) carries a detached PKCS#7 signature over the raw bytes, using an HSM-bound key (Vault Transit or PKCS#11 HSM; see ADR-0004 §11).
  • Append-only audit. li_audit, complaint_triage.audit_trail, attestation_evidence.audit_log, and auditor_access.audit_log are hash-chained and Postgres-rule protected.
  • Time-boxed auditor access. Every read by an external-auditor is audit-logged. Access auto-expires at accessExpiresAt; extensions require CISO + Legal dual-sign.
  • SIEM at-least-once. Events are re-delivered until destination ACK; disk-WAL backs NATS when regulator-side is degraded.
  • Object-lock retention. LI packages + complaints: 7 years. Reports: 7 years. Attestation bundles: permanent. Enforced at the S3 bucket policy level, not application-layer (application cannot delete).

6. Cross-Reference Map

ConceptLives hereAlso referenced by
LI workflowregulator schemaATRA SFTP drop-box; audit-dashboard workbench
Complaint triageregulator.complaintsadmin-dashboard EP-ADMDASH-10 workbench
Report source dataRead-throughcompliance-engine, consent-ledger-service, sender-id-registry-service, cdr-mediation-service, analytics-service (ClickHouse)
SIEM source eventsNATS JetStreamauth-service, compliance-engine, firewall-service, fraud-intel-service, cbc-service, consent-ledger
Attestation controlsregulator.attestationsAll services contribute evidence
HSM signing keysVault TransitReferenced via signing_keys_ref; HSM-held per ADR-0004 §11