Certificates & PKI

Athena runs its own internal certificate authority. On first start the server generates a self-signed Root CA and stores it on disk; from then on every agent that enrolls is issued a per-machine X.509 client certificate signed by that CA, and the server's own gRPC TLS certificate is signed by it too. There is nothing to buy, no public CA to reach, and no internet dependency — the whole trust chain lives inside your network, which is exactly what an air-gapped deployment needs.

This page covers the certificate authority and the certificate lifecycle. For how a host first joins the fleet — installer one-liners and the token handshake — see Agent Enrollment and Registration Tokens.

The Root CA#

When the PKI subsystem initializes, the server looks for a CA certificate and private key on disk. If they exist it loads them. If they are missing on a fresh install (no agents enrolled and no encrypted secrets stored yet) it creates a new self-signed Root CA. If they are missing on a server that already has agents or stored secrets, the server refuses to start rather than silently minting a replacement. The generated CA is a standard certificate authority:

PropertyDefault
SubjectCN=Athena Root CA, O=Athena Deploy Center
KeyRSA 4096-bit, signed with SHA-256
Validity10 years from creation
Basic constraintsCA = true, path length 1
Key usageCertificate Sign, CRL Sign, Digital Signature

The CA is stored under the server's PKI directory (see the CertificatesPath setting below). The CA private key is generated and kept on the server with restricted permissions and never leaves it — only the public CA certificate is ever handed out to agents.

Distribute the CA to trust the server

Agents and browsers need the public CA certificate to trust Athena. Download it from GET api/pki/ca/download in PEM (.crt, for Linux/macOS and manual import) or CER/DER (.cer, for Windows Group Policy deployment), or with the Save-AthenaCACertificate cmdlet. Push the .cer to the Trusted Root store via GPO for a whole domain at once.

The CA key also protects stored secrets#

The Root CA private key does more than sign agent certificates. Athena derives the encryption key for its stored secrets from it, so the same key protects:

In practice this means the database and the PKI are a matched pair. A database paired with a different CA still holds those secrets, but nothing can decrypt them, and the enrolled agents' certificates no longer chain to the server's CA. Back up the PKI directory together with the database, and restore them together — on the virtual appliance, back up /data/athena and /data/pki together. See Data Directories & Backup and Database Restore & Recovery.

If the CA is missing at startup#

If the CA certificate or its private key is missing when the server starts, Athena first checks whether the database depends on the old CA, meaning it holds any agent or any encrypted secret from the list above.

This usually means the database came back without its PKI, for example a restore that skipped the PKI directory, or a storage volume that failed to attach. The fix is to restore the PKI directory from the same backup as the database and start the server again. The log message tells you exactly what is missing.

Starting over with a new CA is a deliberate, lossy choice

If the old CA is truly gone and cannot be restored, you can tell the server to mint a new one anyway by setting Pki:AllowNewCaWithExistingData to true (as an environment variable: Pki__AllowNewCaWithExistingData=true). The server then starts, logs the decision at Critical, and creates a new CA. Every stored secret listed above is lost (re-enter credential passwords, RustDesk passwords and BitLocker PINs, and expect stored BitLocker recovery passwords to be unreadable) and every agent must re-enroll. Set it for one start only, then remove it.

Per-agent certificates#

During enrollment (after the registration token is validated) the server generates a fresh RSA key pair for the agent and issues it a client certificate signed by the Root CA. The certificate has:

The issuance response contains the certificate, its private key, and the CA certificate. The private key is returned to the agent only once at issuance — the server stores just the public certificate (PEM), thumbprint, serial number, and validity dates in its database. Issuing a certificate also stamps the agent's CertificateThumbprint and CertificateExpires fields.

The private key is shown once

The agent's private key is delivered in the issuance/renewal response and is never stored on the server. If it is lost, the agent must obtain a new certificate (renew, or re-register).

How a certificate is validated#

On every authenticated agent connection the server validates the presented certificate. A certificate is accepted only when all of these hold:

Otherwise validation fails with a specific reason — no certificate provided, invalid format, not signed by the CA, expired, not yet valid, revoked, agent not found, or certificate not found. Revocation is checked against the database (the server tracks revoked certificates itself), so a revoked certificate stops working immediately.

Renewal & auto-renewal#

Because agent certificates are short-lived (30 days by default), they are renewed continuously. An agent renews by presenting its current certificate to POST api/pki/renew (certificate authentication, not a JWT). The server verifies the current certificate belongs to that agent, issues a brand-new certificate, and then revokes the old one with the reason "Renewed".

Automatic renewal is enabled by default (EnableAutoRenewal), driven by two settings: certificates are renewed once they are within 7 days of expiry (AutoRenewBeforeDays), and the check runs every 6 hours (AutoRenewalCheckIntervalHours). In normal operation you never renew agent certificates by hand.

Revoking certificates#

An administrator can revoke all certificates for an agent with POST api/pki/agents/{agentId}/revoke and a reason. Revocation:

A revoked agent can no longer authenticate and must re-register to rejoin the fleet. Revoked certificates remain queryable via GET api/pki/revoked for the audit trail.

Extending vs. regenerating the CA#

The Root CA has a long life, but it will eventually approach expiry. There are two very different operations for renewing it — choose carefully:

ExtendRegenerate
EndpointPOST api/pki/ca/extendPOST api/pki/ca/regenerate
Private keyKeeps the same CA keyCreates a new CA key
Existing agent certsStay valid — no disruptionAll revoked — every agent must re-register
EffectIssues a new CA certificate for the same key with fresh validity (default: the configured CA validity, 10 years; or pass additionalYears)Full key rotation for emergencies (key compromise / breach)
Stored secretsUntouched — the key they depend on does not changeRe-encrypted under the new key as part of the operation (see below); no restart needed
Old filesOld CA certificate backed up alongside it (.bak)Old CA certificate and key backed up (.bak)
When to useRoutine renewal as the CA nears expiryLast resort only
Regenerate is destructive

Regenerating the CA revokes every agent certificate and forces the whole fleet to re-enroll. Prefer Extend for normal renewals and reserve regenerate for a confirmed key compromise. Both operations are written to the audit log (CAExtended / CARegenerated; the initial CA logs CACreated).

What regenerate does to stored secrets#

Because the stored secrets depend on the CA key, regenerating the CA carries them over to the new key. Regenerate (from Settings → Security → Certificate, POST api/pki/ca/regenerate, or Invoke-AthenaCACertificateRegenerate) works in this order:

  1. Every stored secret is read with the current key first. If any secret cannot be decrypted, or secrets exist but the server cannot read them at all, regenerate is refused and nothing changes: same CA, same key, same agent certificates. Over REST the call returns HTTP 500 with a message starting "CA NOT regenerated" that says how many secrets were affected; in the console you see "Failed to regenerate Root CA certificate".
  2. The new CA is created.
  3. In a single database transaction, every agent certificate is revoked (reason "CA certificate regenerated - all certificates invalidated") and every stored secret is re-encrypted under the new key.
  4. The new CA goes live immediately. The old CA certificate and key are kept beside it as .bak files, and the server uses the new key without a restart.

Two audit events are written: VaultReencrypted (the description gives the number of secrets re-encrypted) followed by CARegenerated (the number of agent certificates revoked). Saved credentials, RustDesk passwords and BitLocker recovery passwords and PINs keep working after a regenerate. Only the agents need attention: they must re-enroll.

Take a backup after a regenerate

After a regenerate, the database's secrets match only the new CA. Take a fresh backup of the database and the PKI directory together, so that no older PKI backup gets paired with the newer database by mistake.

Monitoring expiry#

To stay ahead of renewals, list certificates expiring soon with GET api/pki/expiring?withinDays=7 (default 7 days). The CA's own metadata — subject, thumbprint, serial, key size, and validity dates — is available from GET api/pki/ca/info, which also flags the CA as expiring soon when it is within one year of expiry. In the console, the Root CA card lives under Settings → Security → Certificate.

Configuration#

PKI behavior is controlled by the Pki configuration section. The defaults are sensible for most deployments:

SettingDefaultMeaning
CertificatesPath./pkiRoot directory for PKI files (CA under ca/, server cert under server/).
CaSubjectCN=Athena Root CA, O=Athena Deploy CenterDistinguished name for the Root CA.
CaValidityYears10Root CA validity in years.
RootCaKeySize4096RSA key size for the Root CA.
KeySize2048RSA key size for leaf certificates (agent client certs and the server gRPC TLS cert). Use 4096 for higher security.
AgentCertValidityDays30Agent certificate lifetime in days.
AutoRenewBeforeDays7Renew a certificate once it is within this many days of expiry.
EnableAutoRenewaltrueEnable the automatic renewal background check.
AutoRenewalCheckIntervalHours6How often the renewal check runs.
ServerCertValidityDays365Validity of the server's gRPC TLS certificate.
ServerCertPassword(random)Password for the server certificate PFX. If empty, a random one is generated and stored.
AllowNewCaWithExistingDatafalseLets the server create a new CA at startup even though the CA is missing and the database already holds agents or encrypted secrets. Those secrets are lost and agents must re-enroll. Use for one start only; see If the CA is missing at startup.

See Configuration for how to set these values.

Roles#

CA download and info (api/pki/ca, ca/download, ca/info) are anonymous — agents need them before they hold a certificate. Agent registration (api/pki/register) is gated by a valid registration token. Renewal (api/pki/renew) and my-certificates require the agent's own certificate authentication. Everything else is gated by a permission: pki.view to list an agent's certificates and view expiring or revoked certificates, pki.revoke to revoke an agent's certificates, and pki.manage to extend or regenerate the CA. Of the built-in roles, only Admin holds these permissions. Callers without the permission receive 403; unauthenticated callers receive 401. See Roles & Permissions and Permission Model & Role Bundles.

REST API#

Method & pathAuthPurpose
GET api/pki/caAnonymousRoot CA certificate (PEM text).
GET api/pki/ca/download?format=pem|cerAnonymousDownload the CA as a .crt (PEM) or .cer (DER) file.
GET api/pki/ca/infoAnonymousCA metadata (subject, thumbprint, serial, key size, validity).
POST api/pki/registerTokenRegister an agent and issue its certificate.
POST api/pki/renewAgent certRenew the calling agent's certificate.
GET api/pki/my-certificatesAgent certList the calling agent's certificates.
GET api/pki/agents/{agentId}/certificatesAdminList an agent's certificates (includeRevoked default true).
POST api/pki/agents/{agentId}/revokeAdminRevoke all of an agent's certificates.
GET api/pki/expiring?withinDays=7AdminCertificates expiring within N days.
GET api/pki/revokedAdminAll revoked certificates.
POST api/pki/ca/extendAdminExtend the CA validity, same key (additionalYears optional).
POST api/pki/ca/regenerateAdminRegenerate the CA with a new key (revokes all agent certs).

PowerShell#

The Athena module ships cmdlets for the CA and certificate operations:

CmdletPurpose
Get-AthenaCACertificateRetrieve the Root CA certificate (PEM). -Server, -Port (default 8443).
Get-AthenaCACertificateInfoShow CA metadata and validity.
Save-AthenaCACertificateSave the CA to a file. -Path (required), -Format pem|cer, -Force.
Get-AthenaExpiringCertificatesList certificates expiring soon. -Days (default 7).
Get-AthenaRevokedCertificatesList revoked certificates. -Page, -PageSize (default 50).
Revoke-AthenaAgentCertificateRevoke all certificates for an agent. -AgentId, -Reason (both required), -Force.
Invoke-AthenaCACertificateExtendExtend the CA validity. -AdditionalYears; prompts for confirmation.
Invoke-AthenaCACertificateRegenerateRegenerate the CA with a new key. High-impact; prompts for confirmation, -Force to skip.
# Export the CA and push it to a domain via GPO (Windows .cer)
Save-AthenaCACertificate -Path "C:\pki\athena-root-ca.cer" -Format cer

# See what's expiring in the next two weeks
Get-AthenaExpiringCertificates -Days 14

# Revoke a decommissioned host's certificates
Revoke-AthenaAgentCertificate -AgentId $id -Reason "Decommissioned" -Force

See the PowerShell Module reference for full cmdlet details.

A self-contained trust chain

Athena's CA is generated and stored entirely on your server — there is no external CA, no OCSP responder to reach, and no internet dependency. Revocation is tracked in the server's own database, so certificate trust works fully offline. See Air-Gapped Operation.