AI Integration
:::info Source
Sourced from services/tenant-service/AI_INTEGRATION.md in the documentation repo.
:::
Blueprint doc 8 of 17. Companion: 03 ai-gateway-service | 13 §8 AI Safety
1. Scope of AI Use
The tenant-service is a light consumer of AI. It does not generate learning content or perform AI grading. Its AI surfaces are focused on operational hygiene:
| Capability | Purpose | Classification (EU AI Act) |
|---|---|---|
| Invite abuse detection | Classify invite email domains for spam/abuse | Limited risk |
| Role suggestion | Suggest roles based on org-unit composition | Limited risk (suggestion-only, HITL required) |
| Dynamic group query assistance | Natural-language → ABAC query translation | Limited risk (suggestion-only, HITL required) |
| Settings anomaly detection | Alert on unusual tenant configuration changes | Limited risk (internal alerting) |
| Org-unit hierarchy suggestion | Given a spreadsheet of users, suggest hierarchy | Limited risk (suggestion-only, HITL required) |
No AI call in the tenant-service ever auto-applies a change. All AI output is advisory; a human must accept.
2. AIClient Port Contract
Per frozen F09 contract, all AI calls route through the AIClient port:
interface AIClient {
classify(req: ClassifyRequest): Promise<ClassifyResult>;
complete(req: CompleteRequest): Promise<CompleteResult>;
completeStream(req: CompleteRequest): AsyncIterable<CompleteChunk>;
embed(req: EmbedRequest): Promise<EmbedResult>;
}
interface ClassifyRequest {
promptId: string;
promptVersion: SemVer;
input: JSONValue;
tenantId: TenantId;
correlationId: ULID;
budgetId: string;
residency: Region;
}
interface ClassifyResult {
label: string;
confidence: number;
provenance: AIProvenance;
}
The tenant-service imports only this port. An infrastructure adapter AiGatewayHttpClient wires to the ai-gateway-service. No vendor SDKs imported directly.
3. Registered Prompts
All prompts live in the prompt registry (frozen F10 + F22) under namespace tenant/:
3.1 tenant/invite.abuse_classifier v1
Purpose: Classify email invitation payloads for spam/abuse.
Input schema:
{
email: string; // redacted username → 'user@domain.com' passed as 'x@domain.com'
tenantAge: ISODuration;
invitesLast24h: number;
domainReputation: 'known_good' | 'known_bad' | 'unknown';
}
Output schema:
{
label: 'legitimate' | 'suspicious' | 'abusive';
confidence: number;
reasons: string[];
}
Policy: Runs pre-call PII redaction; email username hashed. Budget quota: 10k calls/day per tenant. Route: local model first (tiny classifier), escalate to small cloud only on uncertainty.
3.2 tenant/role.suggester v1
Purpose: Given a user's profile snippet and org-unit context, suggest 1-3 role templates.
Input schema:
{
userSnippet: { displayName: string; titleHint?: string }; // no email, no PII
orgUnitPath: string;
existingRoles: string[];
tenantIndustry?: string;
}
Output schema:
{
suggestions: Array<{
roleName: string;
confidence: number;
rationale: string;
}>;
}
HITL: UI shows suggestions; admin must click "Apply". Audit records decisionId linking suggestion to acceptance/rejection.
3.3 tenant/dg_query.nl_to_dsl v1
Purpose: Convert natural language ("engineering learners who joined in the last 90 days") to ABAC ABACQuery DSL.
Input schema:
{
nlQuery: string; // max 500 chars
schemaDescription: string; // canned context
availableFields: string[];
}
Output schema: Structured generation (JSON Schema = ABACQuery).
Policy: Structured output validation required — invalid output returned as unresolved and a fallback UI builder is shown. Prompt injection shield pre-call (mandatory since input is user-controlled).
3.4 tenant/settings.anomaly_detector v1
Purpose: Detect anomalous settings changes (e.g., bulk role deletion, MFA disabled off-hours).
Input schema: Recent audit event sequence (redacted).
Output schema: { anomalyScore: number; explanation: string }.
Policy: Runs on sampled audit events; alerts routed to #sec-tenant-anomalies. Not user-facing.
3.5 tenant/org.hierarchy_suggester v1
Purpose: Given an uploaded CSV of users (name, title, department), suggest an org-unit hierarchy.
Input schema: CSV rows with PII-minimized fields.
Output schema: Suggested OrgUnitTree.
HITL: Admin reviews and edits tree before applying. Acceptance creates actual OrgUnit rows.
4. AIProvenance Invariant
Per frozen F04, every AI-produced artifact carries:
interface AIProvenance {
model: string;
version?: string;
promptId: string;
promptVersion: SemVer;
traceId: string;
decisionId?: string; // present when HITL acceptance occurred
local: boolean;
generatedAt: ISODate;
reviewedBy?: UserId;
reviewedAt?: ISODate;
cost?: { microUSD: number; tokens: { in: number; out: number } };
}
Storage: AIProvenance attached to any persisted AI suggestion (e.g., in authz_decisions_audit.request_context.ai_provenance when AI was consulted).
5. Budget & Quota
Per platform AI governance:
| Capability | Default tenant budget | Hard stop behavior |
|---|---|---|
| Invite abuse classifier | $5/day | Fall back to heuristic rules only |
| Role suggester | $2/day | Hide suggestion UI |
| NL→DSL translator | $3/day | Show empty-state; fall back to manual builder |
| Anomaly detector | $1/day (platform-scoped) | Disable; alert SRE |
| Hierarchy suggester | $10/import | Reject suggestion; manual CSV mapping required |
Budgets enforced by ai-gateway-service; tenant-service receives BUDGET_EXCEEDED error and handles gracefully.
6. Safety & Moderation
Every call routed via ai-gateway-service, which applies:
- Pre-call PII redaction (configurable; enabled by default for tenant data).
- Prompt-injection shield (mandatory for
nl_to_dslsince input is user-controlled text). - Post-call moderation (mandatory for any output surfaced to admins).
- Structured-output schema validation (Ajv against declared output schema).
Violations: event ai.safety_violation.v1 emitted; request fails; fallback UI shown.
7. No-Training Guarantee
All prompts in tenant namespace are tagged no_training: true. The ai-gateway-service enforces this against provider configs (OpenAI org_training_disabled, Anthropic no-train flag, vendor-specific assertions verified at integration test layer).
8. Tenant-Scoped AI Governance
Per-tenant controls (stored in TenantSettings.ai):
interface TenantAISettings {
aiEnabled: boolean; // master gate
aiTutorEnabled: boolean; // downstream feature
allowedCapabilities: string[]; // e.g., ['invite_classifier', 'role_suggester']
forbiddenCapabilities: string[];
localOnly: boolean; // disallow cloud models
residencyStrictMode: boolean; // enforce AI calls stay in homeRegion
opt_out_reason?: string;
}
9. Bias Monitoring
role.suggester is sampled quarterly for demographic parity on consenting tenants. Metrics:
- Do
org_ownersuggestions correlate with proxy gender signals (from first names)? - Do
authorsuggestions correlate with department language (English vs Arabic)?
Output: quarterly bias report; material drift triggers prompt version bump with mitigations.
10. Human Override Paths
- Role suggester: Dismiss/reject button always visible. Reason field optional.
- NL→DSL: Always allow switching to manual query builder.
- Hierarchy suggester: Diff UI lets admin edit any suggested node before accepting.
- Anomaly detector: Ack/dismiss in SRE dashboard.
All overrides logged with decisionId for the quarterly AI safety review.
11. Testing
- Prompt regression suite: fixed inputs → asserted outputs within tolerance (evaluated by ai-gateway-service eval harness on every prompt version bump).
- Safety eval: adversarial inputs (prompt injection, PII exfiltration attempts) must be refused or safe.
- Contract test:
tenant-serviceconsumesAIClient— Pact contract withai-gateway-service. - Fallback test: AI disabled → all tenant flows still work (feature-flag override to disable AI globally).
12. AI Readiness Gate (G5)
| Milestone | Requirement |
|---|---|
| M0 | No AI features required at tenant-service L2 |
| M3 | Invite classifier + role suggester live; prompt regression green |
| M4 | NL→DSL + hierarchy suggester live; bias eval baseline |
| M5 | All five capabilities in production; quarterly external bias audit |