Skip to content
reaatech

Files · Perplexity Security Guardrails for Okta SMB Identity Protection

79 (1 binary, 556.9 kB total)attempt 1

README.md·5259 B·markdown
markdown
# Perplexity Security Guardrails for Okta SMB Identity Protection
 
> A guardrail layer that inspects every AI‑driven Okta operation for PII leaks and prompt injection before it touches your identity fabric.
 
A tutorialized reference solution from [reaatech.com](https://reaatech.com), demonstrating how to build production-grade AI systems with the `@reaatech/*` package family. This recipe uses an Express guardrail proxy alongside the Next.js 16+ App Router shell to protect Okta SMB identity operations.
 
## Problem
 
SMBs that let employees use AI assistants for IT tasks risk exposing sensitive Okta data (names, emails, tokens) or allowing injection attacks that could lock out users or escalate privileges.
 
## Architecture
 
A three-stage guardrail chain runs as Express middleware before every Okta SDK call:
 
| Stage | Guard | Technology |
|---|---|---|
| 1. PII Redact | Detects emails, names, IPs in payload; rejects if present | `@presidio-dev/hai-guardrails` `piiGuard` |
| 2. Prompt Injection | Heuristic scanner via `injectionGuard`; falls back to Perplexity LLM for ambiguous cases | `@presidio-dev/hai-guardrails` + `perplexity-sdk` |
| 3. Okta Policy | Checks the intended Okta API action against a per-role allowlist | Custom `OktaPolicyGuardrail` |
 
The guardrail chain uses `@reaatech/guardrail-chain` for orchestration (budget management, timeout, retry, circuit breaker). LLM calls for injection analysis are tracked via `@reaatech/llm-cost-telemetry`. Malformed Perplexity responses are repaired by `@reaatech/structured-repair-core`.
 
## Packages
 
### REAA
- `@reaatech/guardrail-chain@0.1.0` — Guardrail chain orchestration with `ChainBuilder`, `Guardrail` interface, budget management
- `@reaatech/llm-cost-telemetry@0.2.0``CostSpan` types, `generateId()`, `calculateCostFromTokens()` for LLM cost tracking
- `@reaatech/structured-repair-core@1.0.0``repair()` function that recovers malformed JSON from LLM outputs via graduated repair strategies
 
### Third-party
- `perplexity-sdk@1.0.4` — Perplexity AI API client for prompt injection classification
- `@presidio-dev/hai-guardrails@1.12.0` — PII detection (`piiGuard`), prompt injection detection (`injectionGuard`)
- `@okta/okta-sdk-nodejs@8.1.0` — Okta management API (`userApi`, `groupApi`)
- `express` — Guardrail proxy server
- `zod@4.4.3` — Schema validation for config and LLM output
- `p-limit@7.3.0` — Concurrency limiter for Perplexity API calls
 
## API Endpoints
 
The Express guardrail proxy runs on the configured port (default `3001`). All routes require a JSON body with `action`, `role`, `userId`, `resource`, and `payload` fields.
 
### Users
 
| Method | Path | Description |
|---|---|---|
| `GET` | `/api/okta/users` | List all Okta users |
| `GET` | `/api/okta/users/:userId` | Get a specific user |
| `POST` | `/api/okta/users` | Create a new user |
| `DELETE` | `/api/okta/users/:userId` | Deactivate and delete a user |
 
**Request body shape** (all routes — sent as JSON):
```json
{
  "action": "user:read",
  "role": "admin",
  "userId": "user-id",
  "resource": "users",
  "payload": { "profile": { "firstName": "Jane", "email": "jane@example.com" } }
}
```
 
**Response shapes:**
 
| Endpoint | Status | Response body |
|---|---|---|
| `GET /api/okta/users` | 200 | `[{ "id": "u1", "profile": { ... } }, ...]` |
| `GET /api/okta/users/:userId` | 200 | `{ "id": "u1", "profile": { ... } }` |
| `POST /api/okta/users` | 201 | `{ "id": "new_u", "profile": { ... } }` |
| `DELETE /api/okta/users/:userId` | 200 | `{ "deleted": true }` |
| `POST /api/okta/groups` | 201 | `{ "created": true, "id": "g1" }` |
| All (guardrail rejection) | 403 | `{ "error": "PII detected in request payload", "stage": "pii-redact" }` |
| All (missing fields) | 400 | `{ "error": "Missing required fields: action, role" }` |
| All (server error) | 500 | `{ "error": "message", "stage": "server" }` |
 
### Groups
 
| Method | Path | Description |
|---|---|---|
| `POST` | `/api/okta/groups` | Create a new group |
 
## Role-based Allowlist
 
| Role | Allowed Actions |
|---|---|
| `admin` | `user:read`, `user:write`, `user:delete`, `group:read`, `group:write`, `group:delete` |
| `operator` | `user:read`, `group:read` |
| `viewer` | `user:read` |
 
Unknown roles are denied all actions.
 
## Running locally
 
```bash
cp .env.example .env    # fill in your API keys and Okta credentials
pnpm install
pnpm test               # vitest run with coverage (45+ tests)
pnpm dev                # next dev — guardrail server starts on configured port
```
 
## Project layout
 
```
app/                  Next.js App Router pages
src/
  config/             Environment config loader (Zod-validated)
  guardrails/         Guardrail implementations + chain builder
  middleware/         Express guardrail middleware + error handler
  services/           Okta client, Perplexity client, cost tracker, response repair
  types/              TypeScript type definitions
  server.ts           Express guardrail proxy server
  index.ts            Application entry point
tests/                vitest suite (mirrors src/)
packages/             API references for every dependency
DEV_PLAN.md           build plan for this recipe
```
 
## License
 
MIT — see [LICENSE](./LICENSE).