checkId: check.agent.certificate.validity plugin: stellaops.doctor.agent severity: fail tags: [agent, certificate, security]
Agent Certificate Validity
This Stella Ops Doctor diagnostic proves that each registered agent presents a certificate that is not merely unexpired, but is also trusted, complete, and unrevoked. It is the chain-of-trust companion to check.agent.certificate.expiry, and is aimed at operators hardening agent-to-orchestrator mTLS.
What It Checks
Validates the trust anchor configuration, registered agent certificate thumbprints, and persisted per-agent certificate PEM bundles.
- Trust-anchor bundle health. When
Doctor:Agent:TrustRootPathis configured, the check loads the file and verifies it parses as an X509 certificate, has not expired, and is not expiring within 30 days. - Thumbprint hygiene. Every active (non-Inactive, non-Revoked) agent must have a registered SHA-256 (or legacy SHA-1) hex thumbprint, and no two agents may share the same thumbprint.
- Per-agent pinned chain validation. The ReleaseOrchestrator agent store retains the most recent issued certificate PEM or certificate bundle for each agent. Doctor loads that certificate material, matches it to the registered thumbprint, and builds an
X509ChainwithDoctor:Agent:TrustRootPathas the custom trust store.UntrustedRoot,PartialChain,NotTimeValid, andRevokedstatuses fail the check. - Per-agent revocation/identity probe. When
IAgentCertificateServiceis resolvable, the check also callsValidateAsync(thumbprint)for each registered thumbprint so orchestrator-local revocations remain visible.
In sealed or forced-offline mode (Doctor:OfflineProfile=true or AirGap sealed), the chain uses RevocationMode=NoCheck and does not fetch CRL/OCSP material from the network. In non-sealed mode it uses RevocationMode=Online, allowing the platform to consult OCSP/CRL endpoints when certificates expose them.
The persisted PEM is certificate material only. Private key PEM must never be stored; stores reject PEM that contains private key blocks. Treat the certificate bundle as controlled operational metadata because it identifies agent identities and issuing topology, even though it is not secret key material.
The check requires IAgentStore to be registered in DI; otherwise it will not run.
Evidence collected
TrustRootStatus–not-configured/valid/expiring-soon/expired/missing/parse-error/io-errorTrustRootPath,TrustRootSubject,TrustRootNotAfter(when applicable)ActiveAgents,MissingThumbprint,MalformedThumbprint,DuplicateThumbprintsValidateProbed,ValidateOk,ValidateFailuresAirGapSealed,RevocationModeChainValidated,ChainOk,MissingCertificatePem,ChainFailuresScopedescribes the full trust-anchor, thumbprint, and pinned-chain validation surface.
Why It Matters
A valid certificate expiry date (checked by check.agent.certificate.expiry) is necessary but not sufficient. An agent could present a non-expired certificate that was signed by an untrusted CA, has a broken chain, or has been revoked. Any of these conditions would allow an impersonating agent to receive task dispatches or exfiltrate deployment secrets.
Common Causes
- CA certificate rotated but agent still presents cert signed by old CA
- Intermediate certificate missing from agent’s cert bundle
- Certificate revoked via CRL but agent not yet re-provisioned
- Agent identity mismatch after hostname change or migration
How to Fix
Docker Compose
# Inspect agent certificate chain
docker compose -f devops/compose/docker-compose.stella-ops.yml exec agent \
openssl x509 -in /etc/stellaops/agent/tls.crt -text -noout
# Verify chain against CA bundle
docker compose -f devops/compose/docker-compose.stella-ops.yml exec agent \
openssl verify -CAfile /etc/stellaops/ca/ca.crt /etc/stellaops/agent/tls.crt
Bare Metal / systemd
# Inspect agent certificate
openssl x509 -in /etc/stellaops/agent/tls.crt -text -noout
# Verify certificate chain
openssl verify -CAfile /etc/stellaops/ca/ca.crt -untrusted /etc/stellaops/ca/intermediate.crt \
/etc/stellaops/agent/tls.crt
# Re-bootstrap if chain is broken
stella agent bootstrap --name <agent-name> --env <environment>
Kubernetes / Helm
# Check certificate in agent pod
kubectl exec -it deploy/stellaops-agent -n stellaops -- \
openssl x509 -in /etc/stellaops/agent/tls.crt -text -noout
# If using cert-manager, check CertificateRequest status
kubectl get certificaterequest -n stellaops
kubectl describe certificaterequest <name> -n stellaops
Verification
stella doctor run --check check.agent.certificate.validity
Related Checks
check.agent.certificate.expiry– checks expiry dates (complementary to chain validation)check.agent.heartbeat.freshness– invalid certs prevent heartbeat communication
