Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
node_modules
**/node_modules
**/*.test.ts
**/*.spec.ts
docs/
.git
.gitignore
*.md
!README.md
dist/
**/dist
.env
.env.*
!.env.example
coverage/
.nyc_output
*.log
54 changes: 32 additions & 22 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,23 +1,33 @@
ANTIGRAVITY_API_KEY=
ANTIGRAVITY_BASE_URL=https://api.antigravity.im
CURSOR_API_KEY=
CURSOR_BASE_URL=https://api.cursor.sh
WINDSURF_API_KEY=
WINDSURF_BASE_URL=https://api.windsurf.com
CODEKIT_PROFILE=local-safe
CODEKIT_TIMEOUT_MS=30000
CODEKIT_MAX_RETRIES=3
# Database
DATABASE_URL=postgresql://cku:dev@localhost:5432/cku

# InsForge Foundation
INSFORGE_PROJECT_URL=
INSFORGE_ANON_KEY=
INSFORGE_SERVICE_ROLE_KEY=
INSFORGE_JWT_ISSUER=
INSFORGE_JWT_AUDIENCE=
INSFORGE_JWKS_URL=
INSFORGE_STORAGE_BUCKET_RUN_ARTIFACTS=
INSFORGE_STORAGE_BUCKET_REPORTS=
INSFORGE_STORAGE_BUCKET_LOGS=
INSFORGE_REALTIME_ENABLED=true
CKU_AUTH_MODE=dual
CKU_LEGACY_API_KEYS_ENABLED=true
# Redis
REDIS_URL=redis://localhost:6379

# Auth & Security
CKU_SERVICE_ACCOUNT_SECRET=change-me-in-production
CKU_LEGACY_API_KEYS_ENABLED=false
CKU_ALLOWED_ORIGINS=http://localhost:3000,http://localhost:4000

# Server
PORT=8080
NODE_ENV=development
LOG_LEVEL=info

# InsForge
INSFORGE_ISSUER=https://insforge.example.com
INSFORGE_AUDIENCE=code-kit-ultra
INSFORGE_JWKS_URL=https://insforge.example.com/.well-known/jwks.json

# AI Adapters
ANTHROPIC_API_KEY=sk-...
OPENAI_API_KEY=sk-...
GOOGLE_API_KEY=...

# Optional: Observability
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318

# Optional: GitHub Integration
GITHUB_APP_ID=
GITHUB_APP_PRIVATE_KEY=
GITHUB_WEBHOOK_SECRET=
45 changes: 44 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,50 @@

All notable changes to Code Kit Ultra will be documented in this file.

## [1.2.0] - 2026-03-27
## [1.3.0] - 2026-04-04

### 🚀 Features
- **PostgreSQL Persistence** — All state (runs, gates, service accounts, audit events) now durable via PostgreSQL; no longer lost on restart.
- **Migration Runner** — Database migrations execute automatically on startup with transaction safety.
- **9 Governance Gates** — Full governance gate suite: Scope, Architecture, Security, Cost, Deployment, QA, Build, Launch, Risk Threshold.
- **Gate Rejection** — Reviewers can now reject gates via `POST /v1/gates/:id/reject` with required reason.
- **Service Account Secret Rotation** — `POST /v1/service-accounts/:id/rotate` generates a new 32-byte secret; returned once, never stored plaintext.
- **Session Revocation** — Redis-backed jti blacklist; `DELETE /v1/sessions/me` immediately invalidates a session.
- **API Versioning** — All endpoints now served under `/v1/` prefix; unversioned routes return `410 Gone`.
- **Prometheus Metrics** — `GET /metrics` endpoint with HTTP counters, latency histograms, run lifecycle counters, and gate evaluation counters.
- **Readiness Endpoint** — `GET /ready` gates on both PostgreSQL and Redis connectivity; returns `503` if either is unreachable.
- **Rate Limiting** — Global 100 req/min per IP; 10 req/min for token creation endpoints.
- **Security Headers** — HSTS, X-Frame-Options, CSP, X-Content-Type-Options on all responses.
- **Structured Logging** — Pino JSON logging throughout; all secrets redacted; every request carries X-Trace-ID.
- **Docker Compose** — Full local stack: `postgres:16`, `redis:7`, `control-service`; health-checked and dependency-ordered.
- **Kubernetes Manifests** — Deployment (replicas: 2, rolling update), Service, HPA (70% CPU, 2–10 replicas), ConfigMap, Namespace.

### 🔒 Security Fixes
- **R-01** — Removed hardcoded `"internal-sa-secret-change-me"` fallback; service now throws on startup if `CKU_SERVICE_ACCOUNT_SECRET` is absent.
- **R-02** — Removed hardcoded `"admin-key"` / `"operator-key"` API keys; legacy keys now gated behind `CKU_LEGACY_API_KEYS_ENABLED`.
- **R-03** — Removed `orgId === "default"` tenant isolation bypass from `authorize.ts`.
- **R-04** — PostgreSQL wired to runtime; all state persisted and durable.
- **R-06** — Gate rejection endpoint implemented (`POST /v1/gates/:id/reject`).
- **R-07** — 9 governance gates implemented (was: 1 partial).
- **R-10** — Replaced `Math.random()` with `crypto.randomUUID()` for service account IDs.
- **R-13** — Session revocation via Redis jti blacklist; compromised tokens can be immediately invalidated.
- **R-14** — Service accounts now persisted to PostgreSQL; no longer lost on restart.
- **R-18** — Audit hash chain now uses DB-persisted `lastHash` with advisory lock; survives restarts and multi-instance deployments.

### ⚠️ Breaking Changes
- All API routes moved to `/v1/` prefix. Clients calling unversioned routes (e.g., `/runs`) will receive `410 Gone`. Update all CLI and web UI clients.
- `PORT` now defaults to `8080` (was `4000`).
- Service will not start if `DATABASE_URL` or `CKU_SERVICE_ACCOUNT_SECRET` environment variables are absent.

### 📦 Dependencies Added
- `pg` ^8.11.3 — PostgreSQL client
- `redis` ^4.6.13 — Redis client
- `pino` / `pino-pretty` ^9 / ^10 — Structured logging
- `bcrypt` ^5.1.1 — Secret hashing
- `prom-client` ^15 — Prometheus metrics
- `zod` ^3.22.4 — Request validation



### 🚀 Features
- New version 1.2.0
Expand Down
57 changes: 57 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# ---- Builder Stage ----
FROM node:20-alpine AS builder
WORKDIR /app

# Install pnpm
RUN corepack enable && corepack prepare pnpm@latest --activate

# Copy workspace files
COPY pnpm-workspace.yaml package.json pnpm-lock.yaml ./
COPY packages/ ./packages/
COPY apps/control-service/ ./apps/control-service/
COPY tsconfig.json ./

# Install all dependencies
RUN pnpm install --frozen-lockfile

# Build packages in dependency order
RUN pnpm --filter shared build 2>/dev/null || true
RUN pnpm --filter core build 2>/dev/null || true
RUN pnpm --filter auth build 2>/dev/null || true
RUN pnpm --filter audit build 2>/dev/null || true
RUN pnpm --filter governance build 2>/dev/null || true
RUN pnpm --filter orchestrator build 2>/dev/null || true
RUN pnpm --filter control-service build 2>/dev/null || true

# ---- Production Stage ----
FROM node:20-alpine AS runner
WORKDIR /app

# Create non-root user
RUN addgroup -S cku && adduser -S cku -G cku

# Install pnpm
RUN corepack enable && corepack prepare pnpm@latest --activate

# Copy workspace config
COPY --from=builder /app/pnpm-workspace.yaml /app/package.json /app/pnpm-lock.yaml ./

# Copy only production packages
COPY --from=builder /app/packages/ ./packages/
COPY --from=builder /app/apps/control-service/ ./apps/control-service/

# Install production deps only
RUN pnpm install --prod --frozen-lockfile

# Copy database migrations
COPY db/ ./db/

# Use non-root user
USER cku

EXPOSE 8080

HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
CMD wget -qO- http://localhost:8080/health || exit 1

CMD ["node", "--experimental-specifier-resolution=node", "apps/control-service/src/index.ts"]
58 changes: 53 additions & 5 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,60 @@

## Reporting a Vulnerability

We take the security of Code Kit Ultra seriously. If you find a security vulnerability, please do NOT open a public issue.
We take the security of Code Kit Ultra seriously. If you discover a security vulnerability, please **do NOT open a public GitHub issue**.

Instead, please report it privately:
- **Email**: eybers.jp@gmail.com
- **Response Time**: We aim to respond within 48 hours.
Instead, report privately via one of these channels:

| Channel | Details |
|---------|---------|
| **Email** | eybers.jp@gmail.com |
| **Subject line** | `[SECURITY] Code-Kit-Ultra: <short description>` |
| **Response SLA** | Acknowledge within **24 hours**, patch within **7 days** for critical severity |

Please include:
- Description of the vulnerability
- Steps to reproduce
- Potential impact
- Any suggested mitigations

We will acknowledge your report, keep you updated on our progress, and credit you in the release notes (unless you prefer to remain anonymous).

## Supported Versions

We only support the latest milestone release (e.g., Phase 10 baseline).
| Version | Support Status |
|---------|---------------|
| `1.3.0` | ✅ **Actively supported** — security patches issued within 7 days |
| `1.2.0` | ⚠️ Best-effort only — upgrade to 1.3.0 recommended |
| `< 1.2.0` | ❌ End of life — no security patches |

## Security Model

Code Kit Ultra runs as a multi-tenant orchestration platform. Key security properties:

- **Authentication**: InsForge RS256 JWT → HS256 service account JWT → legacy API key (opt-in)
- **Session management**: Short-lived JWTs (10 min execution tokens); Redis-backed revocation list
- **Tenant isolation**: All queries scoped by `org_id`; cross-tenant requests return `404` not `403`
- **Audit trail**: SHA-256 hash chain in PostgreSQL with advisory lock; tamper-evident
- **Secrets**: Never logged; bcrypt-hashed at rest; plaintext returned once on creation

## Known Mitigated Risks (v1.3.0)

| Risk | Severity | Status |
|------|----------|--------|
| Hardcoded service account secret | Critical | ✅ Fixed in 1.3.0 |
| Hardcoded API keys in source | Critical | ✅ Fixed in 1.3.0 |
| Tenant isolation bypass (`orgId=default`) | Critical | ✅ Fixed in 1.3.0 |
| No session revocation | High | ✅ Fixed in 1.3.0 |
| Math.random() for IDs | High | ✅ Fixed in 1.3.0 |
| In-memory service account store | High | ✅ Fixed in 1.3.0 |
| Module-level audit hash chain | Medium | ✅ Fixed in 1.3.0 |

## Responsible Disclosure

We follow a **90-day coordinated disclosure** policy:
1. Reporter notifies us privately
2. We acknowledge within 24 hours
3. We develop and test a fix
4. Fix released within 7 days (critical) or 30 days (high/medium)
5. CVE filed if applicable
6. Public disclosure after patch is available
25 changes: 21 additions & 4 deletions apps/control-service/package.json
Original file line number Diff line number Diff line change
@@ -1,22 +1,39 @@
{
"name": "control-service",
"version": "1.2.0",
"version": "1.3.0",
"private": true,
"type": "module",
"scripts": {
"start": "tsx src/index.ts",
"dev": "tsx watch src/index.ts"
"dev": "tsx watch src/index.ts",
"test": "vitest run",
"test:watch": "vitest",
"test:coverage": "vitest run --coverage",
"test:smoke": "vitest run test/smoke.test.ts"
},
"dependencies": {
"express": "^4.21.1",
"cors": "^2.8.5",
"chalk": "^5.3.0",
"tsx": "^4.19.0"
"tsx": "^4.19.0",
"pg": "^8.11.3",
"redis": "^4.6.13",
"pino": "^9.0.0",
"pino-pretty": "^10.3.1",
"zod": "^3.22.4",
"bcrypt": "^5.1.1",
"prom-client": "^15.1.3"
},
"devDependencies": {
"@types/express": "^5.0.0",
"@types/cors": "^2.8.17",
"@types/node": "^22.10.0",
"typescript": "^5.6.3"
"@types/bcrypt": "^5.0.2",
"@types/pg": "^8.11.0",
"@types/supertest": "^6.0.2",
"typescript": "^5.6.3",
"vitest": "^1.6.0",
"@vitest/coverage-v8": "^1.6.0",
"supertest": "^6.3.4"
}
}
Loading
Loading