Skip to content

Thumbprint Mode

Thumbprint mode enables mTLS authentication using self-signed certificates verified by their SHA-256 fingerprint.

ScenarioWhy Thumbprint Mode
Quick setupNo CA infrastructure needed
Small deploymentsManual management is feasible
DevelopmentSimple to configure
Isolated networksNo external CA dependencies
POC/testingMinimal setup time
AspectThumbprintCA-Signed
Setup complexityLowMedium
CA requiredNoYes
ScalabilityManual per-agentAutomated
Certificate managementPer-agentCentralized
Best forSmall deploymentsEnterprise
[tls]
auth_mode = "thumbprint"
# Server certificate
cert_path = "/etc/mantis/certs/thorax.crt"
key_path = "/etc/mantis/certs/thorax.key"
# No CA cert needed for thumbprint mode
# But can still be provided for server cert chain
Terminal window
# Enable thumbprint mode
export MANTIS_TLS_AUTH_MODE=thumbprint
export MANTIS_TLS_CERT_PATH=/etc/mantis/certs/thorax.crt
export MANTIS_TLS_KEY_PATH=/etc/mantis/certs/thorax.key
[tls]
cert_path = "/etc/tarsus/cert.pem"
key_path = "/etc/tarsus/key.pem"
# Thorax's server certificate thumbprint (SHA-256, 64 hex chars).
# Required in thumbprint mode: Tarsus verifies the Thorax server cert by
# its fingerprint rather than a CA chain (Thorax presents a self-signed cert).
trust_server_thumbprint = "abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
# CA certificate used to verify the Thorax server and, in listen mode, to
# enforce mTLS on inbound connections. Required in all modes — without it
# Tarsus refuses to start.
ca_cert_path = "/etc/tarsus/ca.crt"

Tarsus automatically generates a self-signed certificate on first run if one is not configured. You can also generate certificates manually using OpenSSL.

Terminal window
# Generate private key
openssl genrsa -out /etc/tarsus/key.pem 2048
# Generate self-signed certificate
openssl req -new -x509 -key /etc/tarsus/key.pem \
-out /etc/tarsus/cert.pem \
-days 365 \
-subj "/CN=$(hostname)/O=Mantis Agent"
ParameterRecommended Value
Key size2048 bits (RSA) or P-256 (ECDSA)
Validity365 days
CNHostname or agent name
SignatureSHA-256
Terminal window
# Get thumbprint from certificate
tarsus show-thumbprint
# Output:
# abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890
# Using OpenSSL
openssl x509 -in /etc/tarsus/cert.pem -fingerprint -sha256 -noout | \
sed 's/SHA256 Fingerprint=//' | tr -d ':' | tr '[:upper:]' '[:lower:]'
FormatExample
Mantisabcdef1234567890abcdef1234567890... (64 chars)
OpenSSLAB:CD:EF:12:34:56:78:90:... (colon-separated)

Convert between formats:

Terminal window
# OpenSSL to Mantis format
echo "AB:CD:EF:12:..." | tr -d ':' | tr '[:upper:]' '[:lower:]'
# Mantis to OpenSSL format (for display)
echo "abcdef12..." | sed 's/../&:/g' | sed 's/:$//' | tr '[:lower:]' '[:upper:]'

Register thumbprint before agent connects:

Terminal window
# 1. On agent: get thumbprint
tarsus show-thumbprint
# abcdef1234567890...
# 2. Share thumbprint securely with admin
# (phone, encrypted email, secure chat)
# 3. Admin pre-registers thumbprint
mantisctl cert pre-register \
--name "web-prod-01" \
--thumbprint "abcdef1234567890..."
# 4. Agent connects and is auto-approved
tarsus run

Approve after agent connects:

Terminal window
# 1. Agent connects (no pre-registration)
tarsus run
# Status: Pending (awaiting approval)
# 2. Admin sees pending registration
mantisctl cert list --status pending
# CLIENT THUMBPRINT HOSTNAME
# unknown-01 xyz789... server.local
# 3. Admin verifies and approves (by registration ID or thumbprint prefix)
mantisctl cert approve "<REGISTRATION_UUID>" \
--notes "Verified web-prod-01 out of band"
# 4. Agent is now authenticated
┌─────────────────────────────────────────────────────────────┐
│ Pending Registrations │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────┬───────────────┬─────────────────────┐ │
│ │ Client │ Thumbprint │ Actions │ │
│ ├────────────────┼───────────────┼─────────────────────┤ │
│ │ unknown-01 │ xyz789... │ [Approve] [Reject] │ │
│ │ unknown-02 │ abc123... │ [Approve] [Reject] │ │
│ └────────────────┴───────────────┴─────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘

Always verify thumbprints through a secure channel:

ChannelSecurity LevelUse Case
In-personHighestHigh-security
Phone callHighVerbal confirmation
Encrypted emailMediumAudit trail
Secure chatMediumQuick verification
Terminal window
# Secure key file permissions
chmod 600 /etc/tarsus/key.pem
chown root:root /etc/tarsus/key.pem
# Verify
ls -la /etc/tarsus/key.pem
# -rw------- 1 root root 1679 Jan 15 10:00 /etc/tarsus/key.pem

Self-signed certificates should be renewed before expiry:

Terminal window
# Check expiration
openssl x509 -in /etc/tarsus/cert.pem -enddate -noout
# notAfter=Jan 15 10:00:00 2026 GMT
# Generate new certificate using OpenSSL
openssl req -new -x509 -nodes \
-keyout /etc/tarsus/key.pem \
-out /etc/tarsus/cert.pem \
-days 365 \
-subj "/CN=$(hostname)/O=Mantis Agent"
# Get new thumbprint
tarsus show-thumbprint
# Re-register with the new thumbprint (revoke old, pre-register new — there is no
# in-place "update thumbprint" verb)
mantisctl cert revoke "$OLD_REGISTRATION_ID" --reason "thumbprint rotation"
mantisctl cert pre-register --name "web-prod-01" --thumbprint "$(tarsus show-thumbprint)"

For deploying multiple agents:

deploy-agents.sh
#!/bin/bash
SERVERS="web-01 web-02 api-01 api-02"
for server in $SERVERS; do
# Get thumbprint from server (assumes SSH access)
thumbprint=$(ssh $server "tarsus show-thumbprint")
# Pre-register in Mantis
mantisctl cert pre-register \
--name "$server" \
--thumbprint "$thumbprint"
echo "Registered: $server"
done

Ansible example:

- name: Get Tarsus thumbprint
command: tarsus show-thumbprint
register: thumbprint
- name: Register with Mantis
uri:
url: '{{ mantis_api_url }}/api/v1/registrations/pre-register'
method: POST
headers:
Authorization: 'Bearer {{ mantis_token }}'
body_format: json
body:
client_name: '{{ inventory_hostname }}'
thumbprint: '{{ thumbprint.stdout }}'
tenant_id: '{{ tenant_id }}'

Problem: Agent shows “Connecting…” but never authenticates

Diagnosis:

Terminal window
# Check agent logs
journalctl -u tarsus -f
# Verify certificate
openssl x509 -in /etc/tarsus/cert.pem -text -noout
# Test connection
openssl s_client -connect thorax.example.com:50051 \
-cert /etc/tarsus/cert.pem \
-key /etc/tarsus/key.pem

Problem: Agent rejected with “thumbprint mismatch”

Diagnosis:

Terminal window
# Get actual thumbprint from agent
tarsus show-thumbprint
# Compare with the registered thumbprint (by registration ID or thumbprint prefix)
mantisctl cert show "agent-registration-id"
# If different, certificate was regenerated

Solution:

Terminal window
# Re-register with the current thumbprint (revoke old, pre-register new)
mantisctl cert revoke "$OLD_REGISTRATION_ID" --reason "thumbprint rotation"
mantisctl cert pre-register --name "agent-name" \
--thumbprint "$(ssh agent-server 'tarsus show-thumbprint')"

Problem: Agent rejected with “certificate expired”

Solution:

Terminal window
# On agent: regenerate certificate using OpenSSL
openssl req -new -x509 -nodes \
-keyout /etc/tarsus/key.pem \
-out /etc/tarsus/cert.pem \
-days 365 \
-subj "/CN=$(hostname)/O=Mantis Agent"
# Get new thumbprint
tarsus show-thumbprint
# Re-register with the new thumbprint (revoke old, pre-register new)
mantisctl cert revoke "$OLD_REGISTRATION_ID" --reason "certificate renewal"
mantisctl cert pre-register --name "agent-name" \
--thumbprint "new-thumbprint-here"
# Restart agent
systemctl restart tarsus
ErrorCauseSolution
no certificate presentedTLS config wrongCheck cert_path path
thumbprint not foundNot registeredPre-register or approve
registration pendingAwaiting approvalApprove in Mantis
registration revokedAgent was revokedRe-register
certificate expiredCert past validityRegenerate certificate

When ready to migrate from thumbprint to CA-signed mode:

  1. Deploy CA infrastructure (see CA-Signed Mode)
  2. Issue CA-signed certificates to agents
  3. Update Thorax configuration to auth_mode = "ca_signed"
  4. Agents re-register with new certificates
  5. Thumbprints still verified (defense-in-depth)

Pre-registration is more secure than post-connection approval:

  • Reduces window of vulnerability
  • Ensures only expected agents connect
  • Creates audit trail before deployment
Terminal window
# Good: descriptive names
mantisctl cert pre-register --name "web-prod-01" --thumbprint "..."
mantisctl cert pre-register --name "api-staging-02" --thumbprint "..."
# Bad: generic names
mantisctl cert pre-register --name "server1" --thumbprint "..."
mantisctl cert pre-register --name "agent" --thumbprint "..."

Maintain records of:

  • Who requested the registration
  • Purpose of the agent
  • Expected thumbprint value
  • Verification method used
Terminal window
# List all registrations
mantisctl cert list
# Review pending approvals
mantisctl cert list --status pending