Machine Identity (mezd identity)

Status: Available — The mezd identity daemon is implemented and working. Bot CRUD, one-time bootstrap tokens, automatic certificate renewal, generation rotation, and bot locking are all functional.

mezd identity provides machine 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-serverAddress of the Mezite auth service (gRPC, port 3025)
join-tokenOne-time bootstrap token generated by an admin
destinationDirectory where certificates are written
renewal-intervalHow often to renew certificates (must be shorter than cert TTL)
mezd identity start (long-running daemon) bash
# Start the bot daemon for continuous cert renewal
mezd identity start \
  --auth-server=mezite.example.com:3025 \
  --join-token=tok-bot-a1b2c3d4e5f6 \
  --destination=/var/lib/mezite/identity/certs \
  --renewal-interval=30m
mezd identity start (one-shot for CI) bash
# Bootstrap once and exit (for short-lived CI jobs)
mezd identity start \
  --auth-server=mezite.example.com:3025 \
  --join-token=tok-bot-a1b2c3d4e5f6 \
  --destination=/tmp/mezite-certs \
  --one-shot

Output Files

After bootstrapping, mezd identity writes the following files to the destination directory:

  • ssh_key — ECDSA private key
  • ssh_key-cert.pub — SSH certificate signed by the User CA
  • known_hosts — Host CA public key for verifying node host certificates
Using bot certificates with msh bash
# After mezd identity writes certificates, use them with msh:
msh ssh --cert=/var/lib/mezite/identity/certs/ssh_key-cert.pub \
  --login=deploy web-server-01

# Or with native ssh:
ssh -i /var/lib/mezite/identity/certs/ssh_key \
  -o CertificateFile=/var/lib/mezite/identity/certs/ssh_key-cert.pub \
  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) Machine (mezd identity)
AuthenticationPassword, SSO, or MFAOne-time join token
LifetimeSingle session (hours)Long-lived daemon (days/months)
RenewalManual re-loginAutomatic, continuous
Certificate TTLMatches session TTLShort (30m-1h), renewed frequently
InteractiveYes (browser, terminal)No (headless, unattended)
RBACUser rolesBot-specific roles (least privilege)

Admin Setup

Step 1: Create a Bot Role

Define a role scoped to exactly the nodes and logins the bot needs. Follow the principle of least privilege.

ci-deployer.yaml yaml
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 Bot Identity

Create bot bash
# Create a bot with mezctl
mezctl bots add --name=github-deploy --roles=ci-deployer --token-ttl=1h

# Output:
# Bot created: github-deploy (roles: ci-deployer)
# Join token: tok-bot-a1b2c3d4e5f6 (expires: 2026-03-24T15:00:00Z)
#
# Use this token with mezd identity:
#   mezd identity start --auth-server=mezite.example.com:3025 --join-token=tok-bot-a1b2c3d4e5f6

Step 3: Run in Your Pipeline

GitHub Actions example yaml
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 \
            --join-token=${{ secrets.MEZITE_BOT_TOKEN }} \
            --destination=/tmp/mezite-certs \
            --one-shot

      - name: Deploy via SSH
        run: |
          msh ssh --login=deploy web-server-01 -- ./deploy.sh

Managing Bots

Bot management bash
# List all bots
mezctl bots ls

# View bot details
mezctl bots show github-deploy

# Rotate a bot's join token (invalidates the old one)
mezctl bots rotate-token github-deploy

# Remove a bot identity
mezctl bots rm github-deploy

Next Steps