Skip to main content

Security

:::info Source Sourced from services/progress-service/SECURITY_MODEL.md in the documentation repo. :::

1. Authentication

  • JWT for internal callers.
  • X-API-Key for xAPI 3rd-party integrations (per-tenant keys; scopes xapi:read, xapi:write).
  • mTLS for inter-service NATS subscription (service identity spiffe://ghasi/prod/progress-service).

2. Authorization

  • progress:statement:write — delivery, assessment, LRS clients.
  • progress:statement:read — admins, compliance officers, self-reads (learner can read own).
  • progress:transcript:read — learner (own), manager of learner's org unit, compliance officer.
  • ABAC: actor.account.name == ctx.user.id for self-read allowance.

3. Multi-Tenant Enforcement

LayerRule
APIX-Tenant-Id matches JWT tid
xAPI agent filterServer narrows to caller's tenant
Postgres RLSUSING (tenant_id = current_setting('app.tenant_id')::uuid)
PartitioningTenant hash sub-partitions for hot months
Analytics firehoseTenant-tagged Kafka messages

4. Data Classification

  • Restricted — statements containing PHI (healthcare tenants), quiz responses in activity_state.
  • Confidential — attempts, completion records, transcripts.
  • Internal — event metadata.

5. Encryption

  • At rest: Postgres TDE + AES-256 on storage layer.
  • In transit: TLS 1.3 + mTLS internal.
  • HIPAA tenants: per-tenant DEK envelope encryption on statements + activity_state.

6. Audit Logging

  • Every read of another user's statements logged to audit table.
  • Every xAPI query with agent filter logged.
  • Daily Merkle-anchored root.

7. xAPI Conformance Security

  • Signed statements (xAPI extension http://id.tincanapi.com/extension/jws): signature verified; actor binding checked.
  • Statements from 3rd-party LRS via xAPI push: source IP allowlisted + API key scoped.
  • Reject statements with authority.account.homePage not in allowlist (tenant config).

8. Threat Model

ThreatMitigation
Forged statement (pretending to be user)Actor verified against JWT sub; S2S signed with service identity
Cross-tenant statement injectionTenant assertion via JWT tid + RLS
Statement tampering at restMerkle-anchored audit log detects changes
Completion record forgeryDerived server-side from statements with passed verb; evidence statement IDs listed
Analytics data exfiltrationPer-tenant Kafka topic ACLs; warehouse RLS
GDPR erasure bypassMandatory participation in erasure saga; replay test validates completeness

9. GDPR Participation

  • Receives gdpr.subject_request.received.v1.
  • Deletes all statements, attempts, completion records for user.
  • Retains anonymized aggregates (subject to tenant policy + legal requirement).
  • Legal hold overrides erasure for tax-relevant data (rare for progress; mostly applies to billing).
  • Emits gdpr.subject_request.acknowledged.v1 within 7 days.
  • Replay test in CI: after erasure, transcripts for user return empty; aggregates show anonymized record.

10. Compliance

  • SOC 2: statements audit log, access logs, quarterly access reviews.
  • HIPAA: progress data for healthcare tenants is PHI; per-tenant key + BAA with providers.
  • FERPA: transcript access requires consent chain recorded in audit log.
  • xAPI spec: conformance-tested via ADL test suite; certificate maintained.

11. Secrets Management

  • DB credentials rotated quarterly via KMS.
  • API keys hashed (argon2id).
  • Raw keys shown once at creation; never logged in full.