Appearance
Deploy
Keel is a set of .NET hosts plus a static web app, backed by PostgreSQL and Redis. Customers who use a private agent (and the Keel Migrate write plane) run the agent image inside their own network.
Components
| Component | What it does | Scale |
|---|---|---|
Keel.Api | REST API, OpenAPI, Server-Sent Events, the migrate, seed and licence verbs | Horizontally |
Keel.Worker | Job queue consumer: scans, profiling, inference, generation, DQ runs, lineage, exports, notifications | Horizontally |
Keel.Scheduler | Quartz ticks: source health checks, drift scans, DQ schedules, certification expiry, audit verification and retention, query-log retention | One active instance |
Keel.Mcp | MCP server per serving endpoint (/mcp/{slug}) | Horizontally, with session affinity |
Keel.SqlGateway | SQL interface (v1.1 beta, feature flag): PostgreSQL wire protocol on port 5433 | Horizontally |
Keel Agent (deploy/agent/Dockerfile) | Keel.Worker in agent mode, run by the customer inside their network: agent-mode sources and the Migrate write plane. See Private agent | One per network segment |
web | The React SPA (web/dist), static files | CDN |
| PostgreSQL 17 + pgvector | Metadata, job queue, outbox, audit, local secret store | Managed service; extensions pgvector and pg_trgm |
| Redis | Serving cache and rate limits | Managed service (optional) |
| OIDC identity provider | Sign-in for people | Any OIDC provider (Keycloak in dev) |
| LLM provider | Optional AI features | Anthropic today |
All hosts emit OpenTelemetry traces, metrics and logs over OTLP and structured JSON logs (Serilog), and expose /health/live and /health/ready (database and queue, plus Redis when configured).
Database roles
Keel uses two roles:
- Migration / owner role (
ConnectionStrings:keel-admin) — runs migrations and owns the schemas. It must be a superuser or haveBYPASSRLS, because a few platform security-definer functions (tenant lookups for authentication, audit pruning) run as it. - Runtime role
keel_app(ConnectionStrings:keel) — not an owner, noBYPASSRLS. The migrator creates it and grants it what it needs. Every tenant table hasENABLE+FORCE ROW LEVEL SECURITY.
Migrations
Run migrations as a pre-deploy job, then roll out the hosts:
bash
dotnet Keel.Api.dll migrate # or: dotnet run --project src/Keel.Api -- migrateThe migrator takes an advisory lock, so concurrent runs are safe. Keel:Database:MigrateOnStartup=true does the same at API start (used by the local stack). Migrations are append-only from the first production deployment; use the expand/contract pattern for zero-downtime changes.
Production checklist
- [ ]
Keel:Auth:Authoritypoints at the tenant IdP; audiencekeel-api;RequireHttpsMetadata=true. - [ ]
Keel:Web:Originis the SPA's origin (CORS is locked to it). - [ ] Secret store:
Keel:Secrets:Provider=keyvaultwithKeyVaultUriand a managed identity — orlocalwith aMasterKeyfrom your vault (never in configuration files). Losing the master key loses every source secret. - [ ]
Keel:Connectors:AllowPrivateNetworksis false (the default) in multi-tenant deployments. - [ ] Redis configured for API and MCP if you run more than one instance (shared rate-limit windows).
- [ ] Exactly one Scheduler instance.
- [ ] SMTP (
Keel:Email) for invitations and notification emails. - [ ] LLM (
Keel:Llm) key if AI features are sold; per-tenant daily token budget reviewed. - [ ] The SPA's Content-Security-Policy allows its inline theme script by hash (it sets the theme before first paint).
- [ ] Backups and restore drill (Backups); audit retention set (Retention).
- [ ] Oracle driver licence text shipped with any self-hosted package.
Not packaged yet
The repository does not yet contain production packaging: container images (planned: chiseled, non-root .NET images with an SBOM and signatures), a Helm chart (deploy/helm/keel) or infrastructure as code (deploy/infra). Until they land, build the hosts with dotnet publish and the web app with pnpm build, and run them on your platform of choice with the configuration above.