# Security Practices

## Overview

AIMEAT handles identity, tokens, and federated trust. Security is non-negotiable. This guide documents the security patterns in use and how to maintain them.

---

## Authentication & Authorization

### Ed25519 Key Pairs

- All owner/agent identities use Ed25519 key pairs (`@noble/ed25519 3.0`).
- Private keys never leave the client (generated client-side, stored by the owner).
- Public keys stored in the node's storage for signature verification.
- **sha512Sync must be set** before using synchronous operations:
  ```typescript
  import * as ed from '@noble/ed25519';
  import { createHash } from 'node:crypto';
  ed.etc.sha512Sync = (...m: Uint8Array[]) =>
    new Uint8Array(createHash('sha512').update(ed.etc.concatBytes(...m)).digest());
  ```

### JWT Tokens

- JWTs use EdDSA algorithm via `jose` library.
- Tokens include: `sub` (GAII), `owner`, `roles`, `iat`, `exp`.
- Token TTL is configurable via `AIMEAT_JWT_TTL`.
- Session revocation: tokens can be revoked via the session storage.

### TOTP 2FA

- Optional second factor via `otpauth` library.
- Backup codes generated on setup.
- Configurable: issuer, period, window, backup code count.

### Role-Based Access

```typescript
// Roles: owner, agent, operator
requireAuth()                    // Any authenticated user
requireRole('owner')             // Owner only
requireRole('agent')             // Agent only
requireRole('operator')          // Operator (first registered owner)
```

**Key rule:** The first registered owner automatically gets the `operator` role.

---

## Input Validation

### Request Validation

- Use Zod or AJV for request body validation at route boundaries.
- Validate all path parameters (cast Express 5 params to `string`).
- Validate query parameters with explicit type checks.
- Reject unexpected fields — don't silently ignore extra input.

### SSRF Protection

- The security E2E tests verify SSRF protection.
- Internal/loopback addresses are blocked in production (allowed in dev mode).
- URL validation on all user-supplied URLs (federation endpoints, callback URLs).

### Path Traversal

- Never construct file paths from user input without sanitization.
- The storage file system uses validated keys, not raw user paths.

### SQL Injection

- SQLite queries use parameterized statements (better-sqlite3 prepared statements).
- MongoDB uses Prisma ORM which parameterizes queries.
- Never interpolate user input into query strings.

---

## HTTP Security Headers

The server sets these security headers (verified by E2E tests):

| Header | Value | Purpose |
|--------|-------|---------|
| `X-Content-Type-Options` | `nosniff` | Prevent MIME sniffing |
| `X-Frame-Options` | `DENY` | Prevent clickjacking |
| `Content-Security-Policy` | Strict policy | Prevent XSS, restrict resource loading |
| `Strict-Transport-Security` | `max-age=...` | Force HTTPS |

### CSP Policy

The CSP policy must include:
- `script-src 'self'` + CDN origins (cdnjs, jsdelivr) for frontend libraries
- `frame-src` for any embedded content
- `connect-src` for API endpoints

**Pitfall:** When adding new frontend dependencies from CDNs, update the CSP policy.

---

## XSS Prevention

### Backend

- All API responses are JSON (`Content-Type: application/json`).
- No HTML rendering in route handlers (see architecture rule).
- Response envelope ensures consistent structure.

### Frontend

```javascript
import { escHtml, escAttr, sanitizeHtml } from '/js/utils.js';

// User-generated content: ALWAYS escape
html`<span>${escHtml(userInput)}</span>`

// Attributes with user data
html`<div title="${escAttr(userInput)}">`

// Rich text (limited HTML allowed)
html`<div dangerouslySetInnerHTML=${{ __html: sanitizeHtml(richContent) }} />`
```

**Critical rule:** Use `escHtml()` only for user data, NOT for `t()` translations. Preact's virtual DOM already escapes text nodes — double-escaping causes `<=` to render as `&lt;=`.

---

## Rate Limiting

### Configuration

Rate limits are tiered and configurable per endpoint category:

```
AIMEAT_RL_GLOBAL=1000      # Global rate limit
AIMEAT_RL_AUTH=100          # Auth endpoints
AIMEAT_RL_WORK=200          # Work queue
AIMEAT_RL_MEMORY=500        # Memory operations
AIMEAT_RL_BOARDS=200        # Board operations
```

### Role Multipliers

Different roles get different rate limit multipliers:
```
operator: 10x
owner: 1x
agent: 1x
anonymous: 0.5x
```

---

## Cryptographic Operations

### Key Generation

```typescript
import { generateKeypair } from '../auth/keypair.js';
const { publicKey, privateKey } = await generateKeypair();
// Keys are Base64-encoded Ed25519 keys
```

### Signature Verification

```typescript
import { verifySignature } from '../auth/keypair.js';
const valid = await verifySignature(publicKeyB64, message, signatureB64);
```

### JWT Creation & Verification

```typescript
import { createJWT, verifyJWT } from '../auth/jwt.js';
const token = await createJWT({ sub: gaii, owner, roles }, config);
const payload = await verifyJWT(token, config);
```

---

## Data Protection & GDPR

### Cascade Delete

Owner deletion cascades to all owned agents, memories, actions, work records, wallet transactions, and board posts. This is the GDPR "right to erasure" implementation.

### Consent Layer

- Consent grants track who can see what data.
- Audit trail of all consent changes.
- Configurable scope and expiry.

### Data Export

Users can export their data via the profile Data Wallet tab (GDPR "right to portability").

---

## Extension Security

V8 isolate extensions run in sandboxed environments:

| Setting | Env Var | Default |
|---------|---------|---------|
| Memory limit | `AIMEAT_EXT_MEMORY_MB` | 8 MB |
| Execution timeout | `AIMEAT_EXT_TIMEOUT_MS` | 1000 ms |
| Code size limit | `AIMEAT_EXT_MAX_CODE_SIZE` | 64 KB |

Extensions cannot access the file system, network, or Node.js APIs directly.

---

## Security Testing

The `test/e2e-security.ts` suite covers:

- SSRF protection (internal IP blocking)
- Header injection prevention
- Auth bypass attempts (missing/invalid/expired tokens)
- Path traversal attempts
- XSS payload rejection
- CORS enforcement
- Rate limit enforcement

**Rule:** When adding new security features, add corresponding tests to the security E2E suite.

---

## Checklist for Security-Sensitive Changes

- [ ] Auth middleware applied to all non-public endpoints
- [ ] Input validated at the route boundary (Zod/AJV)
- [ ] No user input interpolated into queries
- [ ] User-generated content escaped in frontend (`escHtml()`)
- [ ] Rate limits configured for new endpoints
- [ ] Security E2E tests pass (`pnpm test:e2e:security`)
- [ ] CSP headers updated if adding new resource origins
- [ ] No secrets/keys logged or exposed in responses
