Agent Identity (mezd identity)
Status: Available — The mezd identity daemon
is implemented and working. Agent Identity CRUD, one-time bootstrap tokens, automatic
certificate renewal, generation rotation, and agent identity locking are all functional.
mezd identity provides agent identities for CI/CD pipelines,
monitoring systems, and automated services that need SSH access to Mezite-managed
nodes. It authenticates with a one-time bootstrap token, receives short-lived
SSH certificates from the User CA, and automatically renews them without human
interaction. This eliminates long-lived SSH keys and shared service accounts.
What mezd identity Does
mezd identity is a lightweight daemon that manages automated
certificate renewal for non-human identities. It:
- Authenticates to the Mezite auth service using a one-time join token.
- Receives a short-lived SSH certificate signed by the cluster's User CA.
- Writes the certificate and private key to a local directory.
- Automatically renews the certificate before it expires.
- Makes certificates available for other tools (SSH, SCP, Ansible, etc.) to use.
Use Cases
CI/CD Pipelines
Deploy code to production servers via SSH without storing static keys in CI secrets. Each pipeline run bootstraps a fresh certificate that expires after the job completes.
Monitoring and Observability
Monitoring agents that need SSH access to collect metrics or run health
checks can use
mezd identity for continuously renewed certificates.
Automated Deploys
Deployment orchestrators (Ansible, Chef, Puppet) that SSH into managed
nodes can authenticate via mezd identity certificates instead
of static SSH keys distributed across the fleet.
Configuration
mezd identity is configured via command-line flags or a configuration
file. The key parameters are:
| Parameter | Description |
|---|---|
auth-server | Address of the Mezite auth service (gRPC, port 3025; or :443 in single-port ALPN mode) |
token | One-time bootstrap token generated by an admin |
destination-dir | Directory where certificates are written |
cert-ttl | Requested certificate TTL (default 1h) |
renewal-interval | How often to renew certificates (default 20m; must
be shorter than cert TTL) |
# Start the agent identity daemon for continuous cert renewal
mezd identity start \
--auth-server=mezite.example.com:3025 \
--token=$AGENT_IDENTITY_TOKEN \
--destination-dir=/var/lib/mezite/identity/certs \
--renewal-interval=30m # Bootstrap once and exit (for short-lived CI jobs)
mezd identity start \
--auth-server=mezite.example.com:3025 \
--token=$AGENT_IDENTITY_TOKEN \
--destination-dir=/tmp/mezite-certs \
--one-shot Tokens are 64-character hex strings (32 random bytes) — no structured prefix. Store the token in an environment variable or secret manager rather than embedding it on the command line, and never log it.
Output Files
After bootstrapping, mezd identity writes the following files
to the destination directory:
ssh_key— SSH private key (Ed25519)-
ssh_cert— SSH certificate signed by the User CA -
x509_cert.pem— X.509 certificate signed by the User CA -
x509_key.pem— X.509 private key (ECDSA P-256) -
cert_serial— Serial number of the issued SSH certificate -
ssh_known_hosts— Host CA public key for verifying node host certificates
# Use the agent identity-issued SSH cert with the OpenSSH client. The cert and key
# pair is what counts; ssh_known_hosts gives the OpenSSH client the
# Mezite host CA so it can verify node host certs.
ssh -i /var/lib/mezite/identity/certs/ssh_key \
-o CertificateFile=/var/lib/mezite/identity/certs/ssh_cert \
-o UserKnownHostsFile=/var/lib/mezite/identity/certs/ssh_known_hosts \
deploy@web-server-01 How It Differs from Human Auth
mezd identity is designed for non-interactive, long-running use.
The key differences from human authentication (msh login)
are:
| Aspect | Human (msh login) | Agent Identity (mezd identity) |
|---|---|---|
| Authentication | Password, SSO, or MFA | One-time join token |
| Lifetime | Single session (hours) | Long-lived daemon (days/months) |
| Renewal | Manual re-login | Automatic, continuous |
| Certificate TTL | Matches session TTL | Short (30m-1h), renewed frequently |
| Interactive | Yes (browser, terminal) | No (headless, unattended) |
| RBAC | User roles | Agent identity-specific roles (least privilege) |
Admin Setup
Step 1: Create an Agent Identity Role
Define a role scoped to exactly the nodes and logins the agent identity needs. Follow the principle of least privilege.
kind: role
metadata:
name: ci-deployer
description: "CI/CD deploy pipeline SSH access"
spec:
options:
max_session_ttl: 1h
allow:
node_labels:
env:
- staging
- production
logins:
- deploy
deny:
logins:
- root Step 2: Create the Agent Identity
# Create an agent identity with mezctl
mezctl agent-identities add --name=github-deploy --roles=ci-deployer --token-ttl=1h
# Output:
# Agent identity "github-deploy" created.
# Roles: [ci-deployer]
# Token: 8f3a2b1c9d4e5f607182930445566778899aabbccddeeff0011223344556677
#
# Start the agent identity daemon with:
# mezd identity start --auth-server=<fqdn>:443 --token=<token> --destination-dir=/var/lib/mezite/identity
#
# This token can only be used once. Step 3: Run in Your Pipeline
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Mezite tools
run: |
curl -fsSL https://releases.mezite.com/latest/mezite-linux-amd64.tar.gz \
| tar -xz -C /usr/local/bin/ mezd msh
- name: Bootstrap certificates
run: |
mezd identity start \
--auth-server=mezite.example.com:3025 \
--token=${{ secrets.MEZITE_AGENT_IDENTITY_TOKEN }} \
--destination-dir=/tmp/mezite-certs \
--one-shot
- name: Deploy via SSH
run: |
ssh -i /tmp/mezite-certs/ssh_key \
-o CertificateFile=/tmp/mezite-certs/ssh_cert \
-o UserKnownHostsFile=/tmp/mezite-certs/ssh_known_hosts \
deploy@web-server-01 ./deploy.sh Managing Agent Identities
# List all agent identities
mezctl agent-identities ls
# View agent identity details (status, roles, generation, last seen)
mezctl agent-identities status github-deploy
# Remove an agent identity
mezctl agent-identities rm github-deploy
# To rotate credentials, delete the agent identity and re-add it — the previous
# token (or any renewal-state) becomes invalid the moment the agent identity is
# deleted, and the new `agent-identities add` invocation prints a fresh one-time
# token. Next Steps
- RBAC Configuration — Define least-privilege roles for agent identities.
- SSH Access — Understand the SSH connection flow that agent identities use.
- Audit Logging — Monitor agent identity activity in audit logs.