Appearance
Private agent
A Keel Agent runs inside your network and connects to databases Keel's cloud cannot reach. It opens no inbound port: it calls Keel over outbound HTTPS (443, through your proxy if you have one), runs the connector work next to your database with credentials read on its own host or from your vault, and sends back only metadata, statistics, aggregates and the rows a user's query asked for.
What runs through the agent
For a source connected Through a private agent:
- Test connection (manual and the 6-hourly health check)
- Scans and drift scans: harvesting, profiling, relationship and grain probes
- Data-quality rule runs
- Semantic queries: Playground, the serving API, MCP tools and the assistant
Query-log reading (usage-based inference) is not available through an agent yet.
With the licensed Keel Migrate module, the same agent is also the write plane. It runs migration runs (bulk load, change capture, the cutover's final sync) and write-credential scope checks, with a separate write credential it holds. See Run and cut over. To keep an agent read-only, set Keel__Agent__MigrateWrite=false: Keel then never schedules a run on it.
Add an agent
Owners and Admins: Settings › Agents › Add agent. Give it a name, a pool (see below) and optionally a location label. Keel shows the install command with a one-time token once: the token works once and expires after 15 minutes. Pick the package that suits the host.
Docker
bash
docker run -d --name keel-agent --restart unless-stopped \
-v keel-agent-state:/var/lib/keel-agent \
-v /path/to/secrets:/run/secrets/keel:ro \
-e Keel__Agent__ServerUrl=https://keel.example.com \
-e Keel__Agent__EnrollmentToken=kagt_… \
ghcr.io/jrosan/keel-agent:<version>The image is multi-arch (amd64, arm64), runs as a non-root user and is signed; verify it with cosign verify (the command is in the operations guide) and read its SBOM with cosign verify-attestation --type cyclonedx.
Kubernetes (Helm)
bash
helm install keel-agent oci://ghcr.io/jrosan/charts/keel-agent --version <version> \
--namespace keel-agent --create-namespace \
--set serverUrl=https://keel.example.com \
--set enrollment.token=kagt_…One release is one agent (its identity lives on a persistent volume); for a pool of three agents, install three releases with one token each. The chart supports an existing Secret or an ExternalSecret for the token, proxy values, vault settings and workload identity annotations on its service account.
Windows (SQL Server hosts) — unzip keel-agent-<version>-win-x64.zip (no .NET runtime needed) and, as Administrator:
powershell
.\Install-KeelAgent.ps1 -ServerUrl https://keel.example.com -EnrollmentToken kagt_…It installs the KeelAgent Windows service under a virtual account, with its settings and identity readable only by administrators and the service. Run the script of a newer package to upgrade in place; Uninstall-KeelAgent.ps1 [-KeepState] removes it.
On first start the agent creates its own key pair and certificate in its state directory and enrolls; Keel pins the certificate. Keep the state: it is the agent's identity. The agent shows as Online while it sends heartbeats (every 30 s; Offline after 90 s without one).
| Setting | Default | Meaning |
|---|---|---|
Keel__Agent__ServerUrl | — | Keel's public URL |
Keel__Agent__EnrollmentToken | — | One-time token (first start only) |
Keel__Agent__StateDirectory | /var/lib/keel-agent | Agent id, certificate, private key |
Keel__Agent__SecretsDirectory | /run/secrets/keel | One file per secret |
Keel__Agent__Concurrency | 4 | Work items at the same time |
HTTPS_PROXY, NO_PROXY | — | Outbound proxy |
Secrets stay with you
When you connect a source through an agent, enter the name of the secret, not the password. Keel refuses a password for such sources and stores nothing in its own secret store. The agent resolves the name:
- Local (default): a file
/run/secrets/keel/<name>(Docker or Kubernetes secret) or a variableKEEL_SECRET_<NAME>(upper-case, other characters as_). - Azure Key Vault:
Keel__Agent__Vault__Provider=AzureKeyVault,…__AzureKeyVault__VaultUri=https://<vault>.vault.azure.net/, with a managed identity (default), workload identity or a client secret. Names map_and.to-. - AWS Secrets Manager:
…__Provider=AwsSecretsManager,…__AwsSecretsManager__Region=<region>, with keys from the environment, the ECS/EKS task role or the EC2 instance profile; an optionalPrefixis put in front of the name. - HashiCorp Vault (KV v2):
…__Provider=HashiCorpVault,…__HashiCorpVault__Address=https://vault:8200, with a token (VAULT_TOKEN) or AppRole (Auth=AppRole,RoleId, secret id fromKEEL_VAULT_APPROLE_SECRET_ID); the value is the secret'svaluefield (Fieldto change).
Values are cached for five minutes (CacheSeconds), never logged, and a local file or variable of the same name wins so you can override one secret on the host. The agent talks only to Keel, your sources, and the vault you configured (plus its identity endpoint): open exactly those in your firewall.
Pools and high availability
Every agent belongs to a pool (default unless you choose one). A source can use one agent or a whole pool: any healthy agent of the pool that has the source's connector runs its work, and if that agent goes offline or is revoked its work goes back to the pool for another member. A migration run stays with one agent for its whole duration; if that agent is revoked or goes offline, Keel hands the run to another write-capable agent of the same pool, which resumes from the last committed chunk. Move an agent to another pool, rename it or change its location from the fleet screen.
Certificates rotate on their own
Agent certificates are valid for 37 days. At 30 days the agent creates a new key, has Keel pin the new certificate (the request is signed with the current one) and switches over; Keel accepts the old certificate for ten more minutes so nothing in flight is dropped, and running migrations continue. Nothing to do on your side, as long as the state directory is writable and persistent. An agent that stays off for more than 37 days must be enrolled again.
Updates
Keel serves agents of its major version and the previous one; one major behind shows a warning, and an agent two or more major versions behind is refused (shown as Degraded · update required) until it is updated.
Release channels
Each agent follows a release channel: stable (the default), beta, or pinned to one version. Set it per pool (Release channels under the fleet table: every member follows it) or per agent (row menu › Release channel: the agent's own channel wins over its pool's). Pinning an older version is how you roll a fleet back. Channel changes are audited.
Agents that update themselves
The Windows service and plain binary installs (Linux under systemd) update themselves:
- At heartbeat Keel offers the channel's version as a manifest signed with Keel's release key. When it enrolled, the agent pinned Keel's release root (kept offline by Anchor), the same way it pins its certificate; it accepts a manifest only from a release key the root has certified and that has not expired or been replaced. Anchor can rotate its release key without you re-enrolling agents.
- The agent downloads the package from Keel itself — never from another address — and installs it only if its SHA-256 and size match the signed manifest. It then checks that the new version starts on the host.
- It stops taking new work and lets running work finish. Migration runs are never interrupted: the update waits until they are done.
- It replaces its binaries (the settings file is kept), restarts, and the new version must report a healthy heartbeat within 3 minutes. If it does not — or keeps failing to start — the previous version is put back automatically and that version is not tried again. The fleet shows rolled back with the reason.
The fleet screen shows each step (Downloading, Finishing work, Installing) and the outcome. Plain binary installs need a supervisor that restarts the agent when it exits (systemd Restart=on-failure). To manage updates yourself, set Keel__Agent__SelfUpdate=false (Windows: install with -NoSelfUpdate).
Containers (Docker, Kubernetes)
A container never replaces its own binaries: the fleet shows it as managed externally with the version to deploy. Update by pulling the new image (or upgrading the Helm chart) with the same state volume: the identity is kept.
Security
- Every agent request is signed with the agent's private key; in production the same certificate is also required over mutual TLS.
- An agent sees only the work of its sources and pool, in its own workspace; it cannot use the rest of Keel's API.
- Uploads are limited in size, and values of columns suspected to be sensitive are removed on the agent and again by Keel before anything is stored.
- Enrollment, certificate rotations, pool changes and revocation are audited. Revoke stops the agent at once: its next request is refused and its pool work is picked up by another member within seconds.