- External Clients → API Gateway (L2): TLS 1.3 required, JWT/SAML validated
- API → Database (L5/L6): Parameterized queries only, RLS enforced
- MCP Clients → MCP Server: Execution token required, purpose-scoped
- Tenant Isolation: Row-level security enforces strict tenant boundaries
| Threat | Mitigation |
|---|---|
| SQL Injection | SQLAlchemy ORM + parameterized asyncpg queries |
| Horizontal Privilege Esc. | RLS RESTRICTIVE policies on all tenant tables |
| Token Replay | Redis replay store with token JTI tracking |
| Audit Tampering | Chained SHA-256 hashes on audit ledger |
| LLM Prompt Injection | Context sanitization in context_assembler.py |
| Insecure Secrets | All secrets via environment variables / Secret Manager |
| CSRF | SameSite cookies + CORS origin validation |
| Enumeration | Resource IDs are UUIDs, not sequential integers |
All tenant-scoped tables use SECURITY INVOKER RESTRICTIVE policies:
CREATE POLICY tenant_isolation ON students
AS RESTRICTIVE
FOR ALL
TO ioslens_app
USING (tenant_id = current_setting('app.tenant_id')::uuid);The application sets app.tenant_id at the start of each transaction via the database connection pool.
No row from tenant A is ever visible to tenant B.
- Client authenticates via SAML/OIDC → receives JWT
- JWT is validated by
auth_service.py - Client requests an execution token for a specific purpose
- Token service mints a short-lived (15 min) token with:
sub: user IDtenant_id: tenant UUIDpurpose: e.g.,academic_advisingjti: unique token ID (stored in Redis for replay prevention)
- Client passes execution token on each MCP/API call
- Token is verified and JTI checked against Redis on each request
- After 15 min (or explicit revocation), token is rejected
- Development:
.envfile (never committed, listed in.gitignore) - Staging / Production: GCP Secret Manager or AWS Secrets Manager
- Kubernetes: Sealed Secrets or External Secrets Operator
Required environment variables:
DATABASE_URL # postgres connection string
REDIS_URL # redis connection string
JWT_SECRET # HMAC secret for JWT signing
OPENAI_API_KEY # (optional) OpenAI integration
ANTHROPIC_API_KEY # (optional) Anthropic integration
SAML_CERT # (optional) SAML IdP certificate
| Level | Description | RLS Required |
|---|---|---|
| L0 | Public / directory information | No |
| L1 | Internal / aggregate data | Yes |
| L2 | Sensitive / individual PII | Yes |
| L3 | Restricted / FERPA-protected records | Yes + purpose |
| L4 | Regulated / HIPAA / financial | Yes + purpose + MFA |
- FERPA: Student education records protection
- HIPAA: Health information (if applicable)
- SOC 2 Type II: Access control, availability, confidentiality
- NIST 800-53: Federal security controls baseline