Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
a718c3b
feat: add signed synthetic CPU ML foundation
Aug 31, 2026
da1036a
feat: add guarded candidate training cronjob
Aug 31, 2026
0e169a0
security: harden runtime image and worker ingress
Aug 31, 2026
27623f9
security: bind worker events and document go-live evidence
Aug 31, 2026
2100ae6
docs: record post-hardening readiness reassessment
Aug 31, 2026
64cabf7
security: harden financial callbacks and event delivery
Aug 31, 2026
2f2e4f4
fix: clear ML foundation lint findings
Aug 31, 2026
9f58e79
harden remaining core integration boundaries
Aug 31, 2026
e311bf7
preserve integration contracts in hardened clients
Aug 31, 2026
15083e6
gate production releases on verified image evidence
Aug 31, 2026
120a91d
reject local builds in production release gate
Aug 31, 2026
41e6fb0
render production alert routing from approved secrets
Aug 31, 2026
73bbba9
fail closed on production integration defaults
Aug 31, 2026
454d224
validate production CORS origins strictly
Aug 31, 2026
57c3f64
fix: report required integration outcomes accurately
Aug 31, 2026
a3e3ea8
chore: restore orchestration layout
Aug 31, 2026
88e071d
security: fail closed OpenSearch clients
Aug 31, 2026
454ddeb
security: require explicit production IAM config
Aug 31, 2026
7eb359f
security: gate release publishing with environment review
Aug 31, 2026
9acfa3e
security: verify 60 point release evidence
Aug 31, 2026
e63c3ad
security: verify post-merge governance controls
Aug 31, 2026
b748f8b
security: automate guarded production governance setup
Aug 31, 2026
2af437e
security: deny release environment admin bypass
Aug 31, 2026
f480c22
fix: keep governance environment payload within API schema
Aug 31, 2026
36e9f89
fix: remediate orchestration crypto vulnerability
Aug 31, 2026
87b1bca
fix: tidy orchestration crypto module graph
Aug 31, 2026
7b81209
feat(release): normalize CycloneDX candidate evidence
Aug 31, 2026
a110043
chore(release): minimize evidence verifier diff
Aug 31, 2026
835878f
feat(release): collect digest-bound staging evidence
Aug 31, 2026
3ec3c44
Harden staging evidence collector coverage
Aug 31, 2026
7f104c7
Validate immutable evidence inputs strictly
Aug 31, 2026
54b26d0
Reject malformed nested Trivy evidence
Aug 31, 2026
9049f35
Harden synthetic seeding and database pool controls
Aug 31, 2026
7787f66
Govern synthetic fixture coverage exemptions
Aug 31, 2026
1be77c1
Add guarded remaining fixture and evidence CI gate
Aug 31, 2026
1f3327b
Use portable checks in evidence contract gate
Aug 31, 2026
609fa42
ci: block release on protected staging schema drift
Sep 1, 2026
f0866c7
ci: verify private staging database CA bundles
Sep 1, 2026
5beec28
security: add digest-bound break-glass authorization controls
Sep 1, 2026
9bd6577
security: verify break-glass evidence before alert delivery
Sep 1, 2026
8c00059
test: cover elastic break-glass alert idempotency
Sep 1, 2026
c8092c2
security: attest break-glass evidence before alert delivery
Sep 1, 2026
b4601cf
test: harden break-glass ledger tamper coverage
Sep 1, 2026
c9a2fba
security: alert on break-glass evidence tampering
Sep 1, 2026
14211fa
security: classify break-glass manifest tampering
Sep 1, 2026
6da7874
feat: persist DPCO analytics and event retries in PostgreSQL
Sep 1, 2026
81ff4a0
fix: standardize dashboard viewport scrolling
Sep 1, 2026
48eef02
fix: persist webhook delivery audits in PostgreSQL
Sep 1, 2026
aa144f0
fix(lakehouse): make ingest and writer PostgreSQL-durable
Sep 1, 2026
726a70e
fix(security): patch blocked transitive dependencies
Sep 1, 2026
e6bd07b
fix(ledger): enforce durable TigerBeetle transfer contract
Sep 1, 2026
f083f56
fix(payments): persist NIP and RTGS command lifecycle
Sep 1, 2026
d6b5bba
fix(security): require Redis-backed runtime rate limits
Sep 1, 2026
cdfb80e
fix(gateway): persist APISIX route registry and sync evidence
Sep 1, 2026
2bd3e51
fix(authz): require PostgreSQL-backed Permify decisions
Sep 1, 2026
9c21108
fix(auth): require PostgreSQL-backed Keycloak profiles
Sep 1, 2026
62eb179
fix(events): require durable Kafka and Dapr delivery
Sep 1, 2026
4a4991c
fix(payments): require Mojaloop receipt integrity
Sep 1, 2026
21950b3
feat(release): enforce digest-bound production GO evidence
Sep 2, 2026
7e6524b
fix(mobile): migrate portable persistence to postgres
Sep 2, 2026
f328595
fix(ci): bind mobile postgres migration database
Sep 2, 2026
3196367
ci: add isolated extended e2e matrix evidence gate
Sep 2, 2026
c926dc0
fix: harden E2E auth boundary and theme persistence
Sep 2, 2026
e2dfa9d
fix: reconcile release E2E matrix evidence
Sep 2, 2026
fcb0b82
feat: verify staging rollback durability and audit chains
Sep 2, 2026
f1159b7
feat: collect PR readiness evidence read-only
Sep 2, 2026
2af1f89
fix: upgrade orchestration gRPC to v1.83.1
Sep 2, 2026
ab08155
ci: require reviewed visual baselines
Sep 2, 2026
591f421
fix: keep PR readiness collection artifact-free
Sep 2, 2026
2ebdaa8
test: make readiness collector contract formatter-safe
Sep 2, 2026
68cd27b
ci: add guarded visual baseline review reminders
Sep 2, 2026
b7bb2fb
fix: bind visual baseline review to capture ancestry
Sep 2, 2026
fe5c1a4
test: add isolated zero-retry visual diagnostics
Sep 2, 2026
e5333c8
fix: migrate active runtime schema setup to verified ownership
Sep 2, 2026
62a9678
feat(webhooks): add durable shadow queue monitoring
Sep 3, 2026
491f0db
feat(webhooks): add durable active queue worker cutover
Sep 3, 2026
98b4b41
fix(ci): disable TLS for disposable Go test database
Sep 3, 2026
c72034e
fix(tenancy): type RLS startup verification parameters
Sep 3, 2026
a657206
fix(ci): run E2E against root migration ledger
Sep 3, 2026
95a05fa
fix(webhooks): harden lease and migration invariants
Sep 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 42 additions & 9 deletions .env.production.example
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,18 @@ LOCAL_DATABASE_URL=postgresql://ndsep_user:CHANGE_ME_STRONG_PASSWORD@postgres:54
NDSEP_PG_URL=postgresql://ndsep_user:CHANGE_ME_STRONG_PASSWORD@postgres:5432/ndsep_db?sslmode=require

# ── Redis ────────────────────────────────────────────────────
# Production requires a private TLS endpoint. Do not use redis:// or disable certificate verification.
REDIS_PASSWORD=CHANGE_ME_REDIS_PASSWORD
REDIS_URL=redis://:CHANGE_ME_REDIS_PASSWORD@redis:6379
REDIS_URL=rediss://:CHANGE_ME_REDIS_PASSWORD@redis-tls.internal:6380
REDIS_TLS=true
REDIS_TLS_CA_PATH=/run/secrets/redis-ca.crt
REDIS_TLS_REJECT_UNAUTHORIZED=true

# ── Auth / JWT ───────────────────────────────────────────────
JWT_SECRET=CHANGE_ME_AT_LEAST_32_CHARS_RANDOM_STRING
API_KEY_SALT=CHANGE_ME_AT_LEAST_32_CHARS_RANDOM_STRING
WEBHOOK_SIGNING_SECRET=CHANGE_ME_AT_LEAST_32_CHARS_RANDOM_STRING
WORKER_EVENT_HMAC_SECRET=CHANGE_ME_AT_LEAST_32_CHARS_RANDOM_STRING
VITE_APP_ID=your-manus-app-id
OAUTH_SERVER_URL=https://api.manus.im
VITE_OAUTH_PORTAL_URL=https://manus.im
Expand Down Expand Up @@ -59,9 +66,9 @@ TEMPORAL_ADDRESS=temporal:7233
TEMPORAL_NAMESPACE=ndsep

# ── Keycloak (IAM) ───────────────────────────────────────────
# Internal issuer URL used by API services; the public hostname below is
# required for browser redirects and must be covered by the Caddy certificate.
KEYCLOAK_URL=http://keycloak:8080
# Both service and issuer URLs must use TLS in production. The issuer hostname
# must match the Keycloak token `iss` claim and be covered by the Caddy certificate.
KEYCLOAK_URL=https://keycloak.internal:8443
KEYCLOAK_ISSUER_URL=https://sso.ndsep.nitda.gov.ng
KEYCLOAK_REALM=ndsep
KEYCLOAK_CLIENT_ID=ndsep-platform
Expand All @@ -72,22 +79,26 @@ KEYCLOAK_ADMIN_USER=CHANGE_ME_NONDEFAULT_ADMIN_USER
KEYCLOAK_ADMIN_PASSWORD=CHANGE_ME_STRONG_KEYCLOAK_ADMIN_PASSWORD

# ── Permify (Fine-Grained Authorization) ─────────────────────
PERMIFY_URL=http://permify:3476
PERMIFY_ENABLED=true
PERMIFY_URL=https://permify.internal:3476
PERMIFY_AUTH_TOKEN=CHANGE_ME_AT_LEAST_32_CHARS_RANDOM_STRING

# ── TigerBeetle (Financial Ledger) ───────────────────────────
TIGERBEETLE_ADDRESS=tigerbeetle:3001
TIGERBEETLE_CLUSTER_ID=0

# ── OpenSearch (Full-Text Search) ────────────────────────────
OPENSEARCH_URL=http://opensearch:9200
OPENSEARCH_USER=admin
OPENSEARCH_PASS=CHANGE_ME
# Set explicitly to true only after a TLS endpoint and non-placeholder credentials exist.
OPENSEARCH_ENABLED=true
OPENSEARCH_URL=https://opensearch.internal:9200
OPENSEARCH_USER=CHANGE_ME_NONDEFAULT_OPENSEARCH_USER
OPENSEARCH_PASS=CHANGE_ME_STRONG_OPENSEARCH_PASSWORD

# ── Public Edge / APISIX (API Gateway) ───────────────────────
# Caddy is the only service bound to public 80/443. Do not expose APISIX 9080,
# 9443, or 9180 on the host.
NDSEP_PUBLIC_HOST=ndsep.nitda.gov.ng
APISIX_ADMIN_URL=http://apisix:9180
APISIX_ADMIN_URL=https://apisix-admin.internal:9180
APISIX_ADMIN_KEY=CHANGE_ME_32_PLUS_CHAR_RANDOM_ADMIN_KEY

# ── Dapr (Sidecar Runtime) ───────────────────────────────────
Expand All @@ -113,13 +124,35 @@ OPENAPPSEC_OPERATOR_EMAIL=security-operations@ndsep.nitda.gov.ng
OPENAPPSEC_AGENT_TOKEN=

# ── Lakehouse (Data Lake) ────────────────────────────────────
# Keep disabled unless the HTTPS catalog and non-default object-storage credentials
# have been provisioned through an approved secret manager.
LAKEHOUSE_ENABLED=false
LAKEHOUSE_CATALOG_URL=https://lakehouse-catalog.internal:8181
LAKEHOUSE_S3_ACCESS_KEY=CHANGE_ME_AT_LEAST_16_CHARS
LAKEHOUSE_S3_SECRET_KEY=CHANGE_ME_AT_LEAST_16_CHARS
ICEBERG_CATALOG_URL=http://iceberg-rest:8181

# ── CORS ──────────────────────────────────────────────────────
CORS_ORIGINS=https://ndsep.nitda.gov.ng,https://app.ndsep.ng

# ── Security ─────────────────────────────────────────────────
ENABLE_DEMO_LOGIN=false
# Keep disabled unless an approved SMS provider key and accountable recipient are configured.
TERMII_ENABLED=false
TERMII_API_KEY=CHANGE_ME
NDPC_PHONE_NUMBER=+2348012345679
# Required by production Compose; load only from an approved secret manager.
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/CHANGE_ME
PAGERDUTY_INTEGRATION_KEY=CHANGE_ME
NITDA_COMPLIANCE_EMAIL=security-operations@example.ng
PLATFORM_URL=https://ndsep.example.ng
SMTP_HOST=smtp.example.ng:587
SMTP_FROM=ndsep-alerts@example.ng
NETBOX_TOKEN=CHANGE_ME_AT_LEAST_32_CHARS_RANDOM_STRING
RANGER_URL=https://ranger.internal:6080
RANGER_ADMIN_USER=CHANGE_ME_NONDEFAULT_RANGER_USER
RANGER_ADMIN_PASS=CHANGE_ME_STRONG_RANGER_PASSWORD
EVIDENCE_SIGNING_KEY=CHANGE_ME_SECRET_MANAGER_REFERENCE_OR_KEY_MATERIAL

# ── Field-Level Encryption (AES-256-GCM) ─────────────────────
# Generate with: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
Expand Down
43 changes: 43 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# NDSEP security and production-release ownership
#
# The protected production branch must require code-owner review and at least
# two independent approvals. This file routes the security-sensitive paths to
# the repository owner until an authorized administrator replaces or augments
# it with managed security, platform, and compliance teams.
#
# This file does not grant access or replace GitHub branch/environment rules.
# It is intentionally source-controlled so review routing is auditable.

# Dependency-exception governance and scheduled enforcement
/.github/security/pnpm-audit-exceptions.json @munisp
/PNPM_AUDIT_EXCEPTION_POLICY.md @munisp
/scripts/ci/assert-pnpm-audit.mjs @munisp
/scripts/ci/weekly-pnpm-exception-audit.mjs @munisp
/.github/workflows/security-gate.yml @munisp
/.github/workflows/weekly-exception-governance-audit.yml @munisp

# Release artifact, container, and production startup controls
/Dockerfile @munisp
/docker-compose.production.yml @munisp
/Makefile @munisp
/scripts/security/ @munisp
/.github/workflows/ci.yml @munisp
/.github/workflows/emergency-candidate-preflight.yml @munisp
/.github/workflows/digest-bound-emergency-release.yml @munisp
/.github/security/break-glass-authorization-policy.json @munisp
/.github/security/break-glass-alert-delivery-policy.json @munisp
/scripts/ci/verify-break-glass-authorization.mjs @munisp
/scripts/ci/generate-break-glass-evidence.mjs @munisp
/scripts/ci/verify-break-glass-evidence.mjs @munisp
/scripts/ci/publish-break-glass-alerts.mjs @munisp
/.env.production.example @munisp

# Authorization, identity, and policy enforcement
/server/envValidation.ts @munisp
/server/workerEventAuth.ts @munisp
/server/middlewareExtensions.ts @munisp
/server/opensearchConfig.ts @munisp
/server/keycloak.ts @munisp
/server/keycloakAuth.ts @munisp
/infra/opa/ @munisp
/orchestration/keycloak/ @munisp
15 changes: 15 additions & 0 deletions .github/security/break-glass-alert-delivery-policy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"schemaVersion": "ndsep.break-glass-alert-delivery-policy.v1",
"policyId": "ndsep-production-break-glass-alert-delivery",
"repository": "munisp/ndsep",
"environment": "production-release",
"enabled": false,
"allowedSiemModes": [
"splunk-hec",
"elastic"
],
"pagerDutyEndpoint": "https://events.pagerduty.com/v2/enqueue",
"attestationRequired": true,
"externalImmutableRetentionRequired": true,
"noReadinessCredit": true
}
23 changes: 23 additions & 0 deletions .github/security/break-glass-authorization-policy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"schemaVersion": "ndsep.break-glass-authorization-policy.v1",
"policyId": "ndsep-production-break-glass",
"repository": "munisp/ndsep",
"environment": "production-release",
"enabled": false,
"maximumAuthorizationMinutes": 60,
"requiredIssueLabels": [
"incident",
"break-glass"
],
"roles": {
"incident_commander": {
"allowedLogins": []
},
"release_authority": {
"allowedLogins": []
},
"database_authority": {
"allowedLogins": []
}
}
}
Loading
Loading