Certificates and mTLS, a primer
A short primer to read before the SPIFFE post if certificates and TLS are new to you. Part 1 takes a real certificate apart and explains the chain above it and the trust model behind it. Part 2 is what each side of a mutual TLS handshake learns about the other, what it doesn't learn, and the four places the idea goes wrong in production.
Part 1. Certificates
Everything mutual TLS, mTLS for short, proves rests on certificates, so this part is about them alone. TLS is the encryption that protects a connection between two machines, the S in HTTPS. When a TLS connection opens, before any data moves, one side sends the other its certificate, the signed statement of who it is, so the other side can check it before trusting the connection. In ordinary TLS, the kind a browser does with every website, only the server sends one, and the browser checks it. In mutual TLS the client sends one too, and the server checks that. Each side proves itself to the other, and that is the only difference. Part 1 is what one is, a real one taken apart field by field, the chain of signatures above it, and the trust model that decides which chains you accept. Part 2 is the handshake, the opening exchange of messages that sets up a TLS connection.
1. What is a certificate?
In plain English, a certificate authority vouches for a client or a server, that they are who they say they are, and the vouching takes the form of a signed certificate. Everything below is the detail of that one sentence.
A certificate is a signed statement that binds a public key to a name. It isn't a secret. It's handed to anyone who connects.
The name is what the certificate says the key belongs to, and it's the thing the other side checks against what it meant to talk to. For a website it's the host name, the part after https://, such as api.example.com. If you typed api.example.com and the certificate that comes back says api.example.net, the connection fails, and that failure is what the check is for. For a workload, a service running on a platform rather than a site a person visits, it's an identifier the platform gave it, such as spiffe://example.org/payments, and the service on the other end checks that it's talking to payments and not to something pretending to be payments. It is not a person's name. The company's name can appear in a certificate too, and usually does, but the name a verifier matches on is the host name or the workload identifier, and nothing else.
Only the public key is in it, and it came from the owner, not the CA. The owner makes the key pair itself, before it asks anyone for anything, and the CA copies the public half from the request into the certificate exactly as it was sent. A CA signs keys. It never makes them for you. The matching private key is never in a certificate and never travels. It stays where the certificate's owner keeps it, whether a file on the machine, a hardware module, which is a device built to hold keys and never release them, or a key that a small helper program on the same machine, an agent, hands over on request without ever writing it to disk. In the handshake this primer walks through, the only thing it's used for is to sign. The two keys are a pair in the mathematical sense. Anything signed with the private key can be checked with the public key, and nothing checked with the public key could have been signed by anyone without the private one. That pairing is what the handshake in section 6 leans on.
The signature on a certificate is the whole point. Anyone can generate a key pair and write a name next to the public half. The certificate is only worth something because a signer you've decided to trust, a certificate authority, checked that binding and put its own signature on it, and the validity window says for how long that signature stands. The binding is the pairing of a name with a public key. Checking it means two things. The CA confirms that whoever is asking holds the private key that matches the public key. It does that without ever seeing the private key. The asker makes a request, a small file that says the name it wants and the public key it wants bound to that name, and then signs that file with the private key. The CA takes the public key out of the request and checks the signature with it. A signature that checks out against a public key can only have been made with the matching private one, and nothing else, so if the check passes, the asker holds the private key. If someone had copied another party's public key into a request, they couldn't sign it, and the check would fail. And it confirms that the asker is entitled to the name, which on the public web means proving control of the domain, and for a workload means the platform that started it vouches for what it is, the way a SPIRE server does before it issues. SPIRE is software that issues certificates to workloads under the SPIFFE naming scheme, and it's what the post after this one is about.
All of that happens once, when the certificate is issued, and it's over before the certificate exists, so before any connection could use it. When a connection opens, the CA isn't involved. The two sides exchange certificates the CA signed some time ago, and each checks the other's signature against a CA public key it already holds. The CA could be switched off that morning and every handshake would still work. Issuing is one event. Using is every connection after it. Part 2 is only about the second.
That is all a CA checks. It doesn't judge whether the service behind the name is well behaved. A malicious service that controls a name gets a certificate for that name like anyone else, and the certificate says only that this key belongs to this name, signed by this CA. Who is allowed to do what is decided by the party that reads the name, not by the CA that signed it. Part 2 comes back to this, and a later primer on PKI will cover how a CA decides whom to issue to.
A CA isn't a certificate. It's whoever holds a signing key and uses it to sign certificates, in practice a piece of software such as a SPIRE server, an organization's PKI, meaning its own public key infrastructure for issuing certificates, or a public CA's issuing system, guarding a private key. But to check a CA's signature you need its public key, and a CA publishes that the same way everyone else does, in a certificate of its own. That's a CA certificate. So when this primer says a certificate "is a CA certificate", it means the certificate that carries a CA's public key, marked as allowed to sign other certificates. The CA itself is the thing holding the matching private key.
2. A real one, decoded
The format is X.509, RFC 5280. Figure 1 shows the parts and who holds which key. Listing 1 is a real workload certificate of the kind a SPIRE agent hands a workload, generated for this primer and printed with openssl x509 -text. A workload is any running piece of software, a service, a job or a container.
Listing 1: A workload certificate, decoded
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 4096 (0x1000)
Signature Algorithm: ecdsa-with-SHA256
Issuer: O = Example Corp, CN = prod.example.org intermediate
Validity
Not Before: Oct 3 23:02:36 2026 GMT
Not After : Oct 4 00:02:36 2026 GMT
Subject: O = SPIRE
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:9e:97:2f:bc:0b:ce:28:70:1a:d1:7c:b4:9a:aa:
16:84:d0:4c:9c:a7:1e:f5:5c:39:bd:6b:13:01:1c:
c5:8a:23:00:e2:f3:cf:80:0b:40:fd:f1:82:39:e4:
4f:d0:08:e3:6c:78:79:2e:bf:ff:e1:03:95:f6:13:
9f:c0:16:21:92
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Key Usage: critical
Digital Signature
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Subject Key Identifier:
6F:5B:61:D2:50:11:4E:D0:E2:9D:31:0D:92:D9:99:26:BD:B5:EA:B4
X509v3 Authority Key Identifier:
53:8C:DA:4E:FD:C2:0B:B3:F6:42:A5:D2:22:12:3A:66:7B:B7:C6:8F
X509v3 Subject Alternative Name:
URI:spiffe://prod.example.org/billing/payments
Signature Algorithm: ecdsa-with-SHA256
Signature Value:
30:45:02:20:72:16:fb:cb:44:68:7b:ed:6b:63:22:ee:46:41:
4e:8c:8f:c3:21:26:7b:10:41:da:6b:1b:3c:8a:a6:61:43:c3:
02:21:00:af:17:f7:6a:e7:9c:ec:94:3d:1f:10:75:08:df:f1:
99:b1:f8:44:9b:74:f8:a5:df:09:f0:b0:28:33:9e:ec:21
Read it from the top.
- Issuer is the CA that signed it, here an intermediate called
prod.example.org intermediate. Section 4 follows it upward. In the listing's names,Ois the organization andCNis the common name, a human-readable label. - Validity is one hour, from Not Before to Not After. Workload certificates are short-lived on purpose, and section 8 says why that matters.
- Subject is
O = SPIRE, which tells you almost nothing. The identity isn't here. It's at the bottom, in the SAN. - Subject Public Key Info is the owner's public key, an elliptic-curve key on P-256. Elliptic-curve is the kind of mathematics the key pair is built on, and P-256 is the named standard curve it uses. The private key that pairs with it is on the node and appears nowhere in this document.
- X509v3 extensions say what the certificate is for, and section 3 takes them one by one. The last of them, Subject Alternative Name, is the identity,
spiffe://prod.example.org/billing/payments, which is the payments service in theprod.example.orgtrust domain, the group of workloads that share one signing authority. - Signature Algorithm and Signature Value are the intermediate's signature over everything in the
Datablock above, made with the intermediate's private key. Change a single byte of the certificate and it no longer verifies.
3. What the extensions say
The extensions are where a certificate says what it's for, and each one in Listing 1 earns its place.
- Basic constraints says whether the private key that pairs with the public key in this certificate may be used to sign other certificates, through a field spelled
cA. A certificate never signs anything. Keys sign. The certificate records what its owner's key is allowed to sign, and the CA that issued it set that when it signed. Here it'sCA:FALSE, so the payments service's key can sign handshakes but never another certificate. On a CA certificate, the certificate a CA publishes so others can check its signatures, it'sCA:TRUE, sometimes with a path length that limits how many CAs may sit below it. - Key usage says what the key may sign.
Digital Signaturehere, meaning handshakes. A CA certificate saysCertificate Signinstead. - Extended key usage narrows that to a role,
TLS Web Server Authentication,TLS Web Client Authentication, or both. A workload certificate in mTLS usually carries both, because the same workload is a client on some connections and a server on others. - Subject key identifier and authority key identifier are fingerprints, short values computed from a key that identify it. The first names this certificate's own key, and the second names the key that signed it. They're how a verifier finds the next certificate up the chain, and section 4 uses them.
- Subject alternative name, the SAN, carries the names the certificate is good for. A DNS name for a web server, a URI with the SPIFFE ID for a workload, the
spiffe://name at the bottom of Listing 1.
Two of the extensions in Listing 1 are marked critical. RFC 5280 says "A certificate-using system MUST reject the certificate if it encounters a critical extension it does not recognize", so a verifier can't skip basic constraints or key usage by not understanding them. A verifier that ignores the extensions it does understand is worse. It'll accept a client certificate presented by a server, or a leaf being used to sign other certificates.
4. The chain
Usually there's more than one signature between a certificate and the thing you trust. The authority that signs a workload's certificate is itself certified by a higher authority, and so on up to a root that signs itself. That list, from the certificate you were handed up to the root, is the certificate chain. The one at the bottom is the leaf, the ones in the middle are intermediates, and the root is the trust anchor.
Why not have the root sign every certificate directly? Because the root is the one key every verifier trusts outright, and anything that key signs is accepted everywhere. If it signed every workload certificate it would have to be online all the time, reachable by the issuing system, and exposed to everything that system is exposed to. If it leaked, there would be no way to recover short of removing it from every trust store, the set of roots a verifier has chosen to trust, and replacing it, which in a large estate is a project measured in months. So the root signs almost nothing. It signs an intermediate, then goes back offline, often into a hardware module in a locked room, and comes out again only to sign the next intermediate. The intermediate does the daily work. If an intermediate's key leaks, you revoke that one certificate, declaring it untrusted before it expires, and issue a new intermediate from the root, and every trust store stays exactly as it was. A chain also lets one root sit above several intermediates, one per region, environment or purpose, so a problem in one is contained to the certificates it signed.
Here is the chain above Listing 1, from the same three certificates.
| Certificate | Subject | Issuer | Own key identifier | Signed by key | Can sign certificates |
|---|---|---|---|---|---|
| Leaf (Listing 1) | O = SPIRE, SAN spiffe://prod.example.org/billing/payments | prod.example.org intermediate | 6F:5B:61:D2... | 53:8C:DA:4E... | No, CA:FALSE |
| Intermediate | prod.example.org intermediate | Example Corp Workload Root | 53:8C:DA:4E... | FF:DE:44:A3... | Yes, CA:TRUE, path length 0 |
| Root | Example Corp Workload Root | Example Corp Workload Root (itself) | FF:DE:44:A3... | its own | Yes, CA:TRUE |
Follow the key identifiers across the table. The leaf was signed by key 53:8C..., and that's the intermediate's own key, so the verifier checks the leaf's signature with the intermediate's public key. The intermediate was signed by key FF:DE..., which is the root's, so it checks the intermediate's signature with the root's public key. The root was signed by itself, and the verifier stops there because this root is in the verifier's trust store. A self-signature proves only that whoever made it holds the key, so the root's own signature proves nothing more. That's the whole of path validation. Each link is a signature checked with the key one step up, every certificate's validity window is checked on the way, and the walk has to end at a root you already hold.
The intermediate's path length of 0 means it may sign leaves and nothing else. If its key leaked, the attacker could mint workload certificates until it's revoked, but couldn't mint another CA beneath it.
5. The trust model
Which roots you hold is the one input the protocol can't make for you, and it's the whole trust model.
A browser trusts every root in the store it ships with or takes from the operating system. Mozilla's, the one Firefox ships, listed 169 root certificates in the CCADB report, the Common CA Database's public list, on 1 November 2026, 118 of them trusted for websites and the rest for email only, and the stores behind Chrome, Apple's platforms and Windows each hold well over a hundred. Any one of those roots, and every intermediate beneath it, can sign a certificate for any name, and the browser will accept it. That's what makes the public web work without anyone arranging trust in advance, and it's also its weakness. One careless or compromised CA in the list can issue a certificate for your domain, and the web's answer is to watch rather than to restrict, with Certificate Transparency logs that make every publicly trusted certificate visible so a mis-issued one can be spotted after the fact.
A service inside your own estate has no reason to take on that exposure. It should trust exactly one signer, the root that issues certificates for your workloads, and nothing else. When you federate with a partner, which means agreeing to accept identities their signer issued, you add their root for their trust domain only and keep it separate, so a certificate is checked against the root for the domain it claims to belong to. A validator that merges every partner's roots into one pool has let every partner sign for your own domain.
Revocation is the last piece. A certificate can be revoked before its window ends, through a revocation list or an online status check, but in practice checks are slow, often skipped, and fail open when the status service is down, meaning the certificate is accepted unchecked. Workload estates mostly don't rely on them. They make certificates short-lived instead, an hour as in Listing 1, so a certificate that should no longer be trusted stops being valid on its own within the hour. That trade, short lifetimes in place of revocation, comes back in section 8.
So the certificate is public, the chain says who vouches for it, and the root you chose decides whether that vouching counts. What's left is proving that whoever presents the certificate holds the private key. That's the handshake.
Part 2. Mutual TLS
6. What the handshake proves
Two different kinds of key are at work in a handshake, and it helps to keep them apart. The certificate's key pair is long-lived and proves who you are. It's only ever used to sign. The session keys are brand new for every connection and protect the traffic. They're only ever used to encrypt. Figure 2 shows where each comes in.
In TLS 1.3 the client opens with a ClientHello that carries a key share, the public half of a key pair the client made a moment ago for this connection and will throw away when it ends. The server answers with a ServerHello carrying its own key share. Each side now combines its own one-time private key with the other side's public share, and the mathematics of the exchange, in practice elliptic-curve Diffie-Hellman, a key agreement method named for its inventors, gives both sides the same secret without that secret ever crossing the wire. Both derive the session keys from it, and from this point on everything in the handshake is encrypted. Those are the "exchanged keys" RFC 9846 refers to below.
Encrypted, but not yet authenticated. So far the client has agreed a secret with someone, but it doesn't yet know with whom. That's what the rest of the handshake is for. The server sends its certificate chain, a CertificateVerify, and a Finished. The CertificateVerify is the important one. It's a signature over everything in the handshake so far, made with the server's private key, and it's the step that proves possession, because a certificate can be copied but the signature over this particular handshake can't be produced without the key.
The client now does four things in order, and a verifier that skips any of them hasn't verified anything.
- Build the chain from the presented certificate up to a trust anchor the client already holds, checking each signature on the way. RFC 5280 calls this path validation. The anchor has to be one the client already holds in its own trust store before the connection starts. The server sends its chain, and that chain may even include a root, but the client never trusts a root because the server sent it. Anyone can make a root and sign a certificate under it, so a client that accepted whatever root arrived in the handshake would accept anyone. A chain that ends at a signer the client didn't already hold is refused. Where the client got that signer is the question, and the answer is that it never came from this connection. It was put there ahead of time, out of band. On the public web the browser or the operating system ships a list of root certificates with the software and updates it with the software, and that list is the trust store. In a private PKI the operator puts the root there, as a file on the machine or baked into the container image, or, for a workload, as a bundle the platform hands over along with the workload's own certificate, which is what a SPIRE agent does. So the client holds the signer's public key before the first packet, and the server only has to send the intermediates that sit between its own certificate and that root. Section 5 is about which roots a client should hold.
- Check the validity window of every certificate in the chain against the current time.
- Check that the name in the certificate is the name the client meant to reach. On the web that's the DNS name against the SAN. Inside an estate it can be a SPIFFE ID in the URI SAN, which is what mTLS, SPIFFE and SPIRE, part 3 of the identity series, is about.
- Check the CertificateVerify signature with the public key from the leaf.
Only after all four, and after checking the server's Finished against the keys it derived, does the client send its own Finished, and only after that does it send application data. The server is allowed to send application data as soon as its own Finished is out, before the client's certificate has arrived, which in mutual TLS means sending to a peer it hasn't authenticated yet, so an mTLS server waits. In the words of RFC 9846, section 2, the Finished message "provides key confirmation for the shared secrets established in the handshake, binds the endpoint's identity to the exchanged keys". Key confirmation means it proves both sides derived the same session keys, since it's computed with a key taken from the shared secret over everything said so far. Binding the identity means the certificate and CertificateVerify that came before it are inside what it covers, so the identity that was proved and the keys that will protect the traffic belong to the same connection and can't be split apart by anyone in the middle. Everything that follows on the connection is encrypted and integrity-protected, so any change in transit is detected, with those session keys, which is why what happened in the handshake applies to the whole connection, for better and, as section 8 says, for worse. And because the one-time key pairs are thrown away when the connection closes, a recording of the traffic can't be decrypted later even by someone who steals the certificate's private key. That property is called forward secrecy. RFC 8446 made it the rule and RFC 9846 keeps the sentence, in section 1.3, "Static RSA and Diffie-Hellman cipher suites have been removed; all public-key based key exchange mechanisms now provide forward secrecy." A cipher suite is the named set of algorithms a connection uses, and the static ones the quote mentions reused one long-term key for every connection's key exchange.
Mutual TLS adds one thing. The server includes a CertificateRequest, and the client sends its own chain and its own CertificateVerify before its Finished, so the server runs the same four checks on the client. At the end of a mutual handshake each side knows the other holds the private key for a certificate that chains to a signer it chose to trust, bearing a name it recognizes. That's the entire guarantee. It's strong because neither half can be faked. A copied certificate can't produce the CertificateVerify, because the CertificateVerify is a signature over this connection's own handshake messages, made with the private key, and the thief has the certificate, which is public, but not the private key, which never left its owner. The verifier checks that signature with the public key inside the certificate, and only the matching private key could have made it. A signature captured from some earlier connection is no use either, because the messages it signed included that connection's fresh random values, not this one's. And a certificate from a signer you didn't choose doesn't chain. It's narrower than people assume because it answers one question, which identity opened this connection at the moment it opened, and people read three or four more answers into it. It says nothing about what that caller may do, nothing about which user is behind it, nothing about whether the identity is still good an hour later, and nothing about who was on the far side of a proxy. Section 7 takes those one at a time.
7. What it doesn't prove
Four things are routinely read into an mTLS connection that aren't in it.
It doesn't prove authorization. The server knows who connected. Whether that caller may do what it's about to ask is a separate decision, made in policy, keyed on the name the certificate carried. Section 6 of mTLS, SPIFFE and SPIRE puts that decision in two layers, may this workload connect to me at all, enforced before a byte of application data is read, and may it do this thing for this user, decided in the application. A deployment that treats "the handshake succeeded" as "the request is allowed" has one layer where it needs two.
It doesn't identify the user. A client certificate names the software that opened the connection, a service, a sidecar, a gateway. A sidecar is a small proxy deployed beside a service to handle its connections for it. If a human is behind the request, their identity rides inside the request, as an access token or a transaction token, and is checked separately. Who is calling comes from the connection, and for whom comes from the token. Transaction tokens, part 2 of the series, is about the second half.
It doesn't re-check. The four checks run once, at the handshake. A certificate that expires ten minutes into a connection doesn't end the connection, and a certificate that's revoked an hour in isn't consulted again, because nothing in TLS re-checks the certificate after the Finished. TLS 1.3 has an optional post-handshake client authentication, where the server asks the client for a certificate again mid-connection, but it runs the same checks on fresh material, almost nothing deploys it, and it never re-checks the server. Section 8 comes back to this.
It doesn't survive a proxy. The guarantee is between the two endpoints of the TLS connection. If something in the middle terminates TLS and opens a new connection onward, the thing on the far side has a guarantee about the middle, not about the original client. Section 8 comes back to this too, because it's the failure that catches the most people.
8. The four places it goes wrong
Where TLS terminates. A load balancer or an ingress, the proxy at the edge of a cluster, that terminates TLS in front of a service sees the client's certificate. The service behind it sees the balancer's. Either the balancer passes the connection through untouched, which is passthrough and keeps the handshake end to end, or it's itself a workload with its own certificate, re-originates mTLS to the backend, and carries the original client's identity some other way, usually a header such as X-Forwarded-Client-Cert that the backend accepts only from that balancer. The header is an assertion by the proxy, not a proof by the client, and the backend's trust in it is exactly as good as its trust in the proxy that set it. A design that doesn't know where its TLS terminates doesn't know who its callers are.
Rotation. Workload certificates are short-lived, an hour in SPIRE's defaults, and are replaced continuously. New connections use the new certificate. Connections that are already open keep the identity they were authenticated with until they close. So a workload whose identity has been revoked, or whose certificate has rotated to a narrower name, lingers on every connection it opened before the change, for as long as those connections live. Long-lived connections, gRPC channels and database pools among them, make rotation a policy question rather than a mechanism. The usual answer is a maximum connection age, after which the client reconnects and the handshake runs again against current material.
Pinning. Pinning means refusing any certificate except one you've hard-coded. Pin a leaf and the first rotation breaks every client that pinned it, which in a short-lived-certificate world is within the hour. Pin the trust anchor instead, which is the thing that doesn't rotate, or in SPIFFE terms validate against the trust bundle, the set of CA certificates a domain publishes, for the peer's domain and nothing else. Keep the set of signers you accept small, chosen by you, and separate per trust domain, for the reason section 5 gave. One pool of everyone's roots lets everyone sign for you.
The connection that outlives the credential. This is the previous three in one sentence. The handshake proved something at a point in time, the connection keeps using that proof for as long as it stays open, and nothing in the protocol asks the question again on its own. For a request-sized connection that's harmless. For a channel that stays open for hours it's a gap between the authority that was checked and the authority that exists now, and it has to be closed outside TLS, by connection age limits, by the server dropping connections when a revocation arrives, or by the application re-checking at its own layer. The same shape appears with user tokens on long-lived connections, and gets its own post.
9. A verifier, in plain words
Every mTLS verifier, whether it's a library callback or a proxy's configuration, does these five things in this order. They're the four checks from section 6 plus one that TLS libraries do for you and that a proxy configuration can forget, the key usage check.
- Build the chain from the presented certificate to a trust anchor it chose. Not the operating system's store, not any CA that happens to sign, but the anchor for this peer's trust domain and only that one.
- Check that every certificate in the chain is inside its validity window right now.
- Check that the name it meant to reach is in the SAN, a DNS name for a web peer, a URI with the SPIFFE ID for a workload peer. The subject field isn't where the name lives.
- Check that the key usage and extended key usage allow what this certificate is being used for. A leaf isn't a signer, and a server certificate has to be presented by a server.
- Check the CertificateVerify signature with the certificate's public key. That's possession proved.
Then, and only then, it authorizes on the name. May this identity connect to me at all, at the transport, and may it do this particular thing, in the application. Neither question was answered by steps 1 to 5.
Most TLS libraries do steps 1, 2, 4 and 5 for you, and skip step 3 for workloads unless you do it yourself, because by default they compare a DNS name and a SPIFFE ID isn't one. Most proxies do all five steps and then stop, so the authorization that should follow is left to a configuration nobody wrote. Those are the two places to check first when you're reviewing an mTLS deployment. Does it check the name it actually meant to reach, and does anything decide what the caller is allowed to do once the handshake succeeds?
10. Where this goes next
The thing this primer leaves open is how a workload gets a certificate with the right name in the first place, how it gets a fresh one every hour without a human in the loop, and how two estates that trust different signers can verify each other. That's mTLS, SPIFFE and SPIRE, part 3 of the identity series. If you came here from it, go back to its section 6. The handshake there is this one with SPIFFE IDs in the names.
Glossary
| Term | Meaning in this primer |
|---|---|
| Authority key identifier | An extension naming the key that signed this certificate. It matches the subject key identifier of the issuer's certificate, which is how a verifier finds the next link up the chain. |
| Basic constraints | The extension that says whether the private key paired with a certificate's public key may sign other certificates, through a field spelled cA, and for a CA how many CAs may sit below it (the path length). Marked critical. |
| CA certificate | The certificate a CA publishes so others can check its signatures. It carries the CA's public key and is marked CA:TRUE in basic constraints, with key usage Certificate Sign. Roots and intermediates are CA certificates. |
| CA | Certificate authority. Whoever holds a signing key and uses it to sign certificates, in practice software guarding a private key. Not itself a certificate. It publishes its public key in a CA certificate. In a workload estate, the one signer you've chosen to issue your workloads' certificates. In SPIRE, the open-source issuer the SPIFFE post covers, it's the SPIRE server, which holds either the root itself or an intermediate signed by a CA your organization already runs. |
| CCADB | The Common CA Database. A shared record of root and intermediate certificates, run by Mozilla and used by several browser and operating system makers to manage the roots they trust. Its public reports are where the root counts in section 5 come from. |
| Certificate chain | The list from the certificate you were handed (the leaf) through any intermediates to a root. Verified by checking each signature up the list until you reach an anchor you already hold. |
| Certificate | A signed statement binding a public key to a name, with a validity window and extensions, in the X.509 format. Public, and handed to anyone who connects. Site glossary, Certificate. |
| CertificateRequest | The TLS message a server sends to ask the client for a certificate. Its presence is what makes a handshake mutual. |
| CertificateVerify | A signature over the handshake so far, made with the sender's private key. The step that proves the sender holds the key for the certificate it presented. A copied certificate can't produce it. |
| Cipher suite | A named set of algorithms the two sides of a TLS connection agree to use. Older TLS versions had suites with static RSA or static Diffie-Hellman key exchange, which reused one long-term key for every connection and so had no forward secrecy. TLS 1.3 removed them. |
| ClientHello | The first message of a TLS handshake. Names the TLS versions and encryption algorithms the client supports, and carries add-on fields called extensions, among them the client's key share and the server name it intends to reach. |
| Common name (CN) | A free-text name field inside a certificate's subject or issuer, printed as CN =. Beside it, O = is the organization field. Both are labels for people to read. Verifiers read the name from the SAN. |
| Critical extension | An extension a verifier must understand. RFC 5280 says a certificate-using system "MUST reject the certificate if it encounters a critical extension it does not recognize". |
| Diffie-Hellman | A key agreement method, named for its inventors. Each side sends a public value and keeps a private one, and both arrive at the same secret, which someone who saw only the public values can't compute. TLS 1.3 usually runs the elliptic-curve version. |
| Elliptic-curve key | A key pair built on elliptic-curve mathematics, which gives the same strength as the older RSA kind of key at a fraction of the size. P-256 is the standard curve used in Listing 1, also printed as prime256v1. |
| Estate | Everything one organization runs, its services, machines, clusters and the networks between them, taken together. Used here for the inside, where you choose the signers and issue the certificates yourself, as opposed to the public web, where the signers are chosen for you by the browser or the operating system. |
| Extended key usage | The extension that narrows a key to a role, server authentication, client authentication, or both. |
| Fail open | What a check does when it can't get an answer and lets the request through anyway. A revocation check that fails open accepts the certificate when the status service can't be reached. |
| Federation | Two organizations agreeing to accept workload identities issued by each other's signer. Each adds the other's root for the other's trust domain only. Site glossary, Federation. |
| Fingerprint | A short value computed from a key or a certificate, usually a hash, that identifies it. The subject and authority key identifiers are fingerprints of keys. |
| Finished | The last handshake message from each side. In the words of RFC 9846 it "provides key confirmation for the shared secrets established in the handshake, binds the endpoint's identity to the exchanged keys". The client sends application data only after both. |
| Forward secrecy | The property that a recording of past traffic can't be decrypted even if a long-term private key is stolen later, because the session keys came from one-time key pairs that no longer exist. In TLS 1.3 every key exchange that uses a key share has it. |
| gRPC | A widely used remote procedure call framework that runs over HTTP/2. A gRPC channel keeps a connection open and reuses it for many calls, so it can live for hours. |
| Handshake | The exchange of messages at the start of a TLS connection, before any application data. In it the two sides agree on the session keys and prove their identities. |
| Hardware module | A device built to hold private keys and sign with them without ever releasing them, so the key can't be copied off the machine. Often called a hardware security module, HSM for short. |
| Ingress | The proxy at the edge of a cluster that receives connections from outside and routes them to the services inside. The name comes from Kubernetes. |
| Integrity protection | A check value computed with the session keys and sent with each encrypted record, so the receiver detects any change made in transit and closes the connection. |
| Intermediate | The CA certificate of a CA that sits between the leaf and the root. Signed by the one above it, signs the one below. Present so the root's private key can stay offline. |
| Key share | The public half of a one-time key pair each side sends in its hello message. From the two shares both sides compute the same secret without sending it, and the session keys come from that secret. Unrelated to the certificate's keys. |
| Key usage | The extension that says what a key may sign, handshakes (digital signature) or other certificates (certificate sign). |
| Leaf | The certificate at the bottom of the chain, the one that names the workload or the server. It can't sign other certificates. The one that rotates. |
| Mutual TLS (mTLS) | TLS in which the client presents a certificate too, so each side proves its identity to the other. In ordinary TLS only the server does. Site glossary, Mutual TLS (mTLS). |
| Passthrough | A load balancer forwarding the TLS connection untouched (TCP mode), so the handshake happens end to end between the original client and the backend. The alternative to termination. |
| Path validation | RFC 5280's name for verifying a chain. Each signature checked against the key in the certificate above it, every validity window checked, the chain ending at a trust anchor you hold. |
| Pinning | Refusing any certificate except one hard-coded in advance. Safe when the pinned thing is a trust anchor, and broken on the first rotation when the pinned thing is a leaf. |
| PKI | Public key infrastructure. The CAs, certificates, rules and tooling an organization uses to issue and manage certificates. |
| Private key | The secret half of a key pair. Never in a certificate, never sent. Stays with its owner, in a file, a hardware module or a key handed over a local socket, and is used only to sign, in the CertificateVerify and when acting as a CA. |
| Public key | The half of a key pair that's in the certificate. Checks signatures made with the private key. Not a secret. |
| Revocation | Declaring a certificate untrusted before its validity window ends, through a revocation list or an online status check. Often slow or skipped in practice, so workload estates rely on short lifetimes instead. |
| Rotation | Replacing a certificate with a fresh one before the old one expires, hourly in SPIRE's defaults. New connections use the new one, but open connections keep the identity they were authenticated with until they close. |
| Self-signed | A certificate whose issuer is itself. A root is self-signed. Its signature proves only that the maker holds the key, and it's trusted only because you put it in your trust store. |
| Session keys | The keys that encrypt and protect one connection's traffic. They're symmetric, which means both sides hold the same key and it both encrypts and decrypts. Derived by both sides from the secret the key shares produced, never sent, and gone when the connection ends. |
| Sidecar | A small proxy deployed beside a service, on the same host, that handles the service's network connections on its behalf, often including mTLS. Site glossary, Sidecar. |
| Subject alternative name (SAN) | The X.509 extension that carries the names a certificate is good for. A DNS name for a web server, or a URI with the SPIFFE ID for a workload. Verifiers read the name from here, not from the subject field. |
| Subject key identifier | An extension naming this certificate's own key. The authority key identifier of every certificate it signs points back to it. |
| Termination | A proxy or load balancer ending the client's TLS connection at itself and opening a new one onward. Whatever is behind it sees the proxy's identity, not the client's. |
| TLS | Transport Layer Security. The protocol that encrypts a connection between two machines and proves the server's identity with a certificate, the S in HTTPS. This primer describes version 1.3. Site glossary, TLS. |
| Trust anchor (root) | The certificate at the top of a chain, self-signed, that nobody vouches for and that you've chosen to trust on your own authority. The one input the protocol can't make for you. |
| Trust store | The set of root certificates a verifier has chosen to trust, kept as a file or a system list. A chain is accepted only if it ends at a root in the store. Browsers and operating systems ship one, and a workload should hold only the root for its own estate. |
| Validity window | The not-before and not-after times in a certificate. Checked for every certificate in the chain at the handshake, and not again. |
| Workload | A running piece of software, a service, a job or a container, as opposed to a person. In this primer, the thing a workload certificate names. Site glossary, Workload. |
| X-Forwarded-Client-Cert | A header a terminating proxy adds to carry the original client's certificate details to the backend. An assertion by the proxy, trusted exactly as far as the proxy is, and accepted only from it. |
Comments
Signed with your GitHub account, identity required, drive-by anonymity not offered.