Business Challenge
#70 closed by saying that Roles Anywhere moves half your authorisation decision into your PKI. This is that PKI. And the thing about a private CA is that creating one takes an afternoon while living with one takes years, so nearly every consequential decision gets made before anybody has operated it.
Start with the sentence that defines the risk: “When a CA certificate expires, all of the certificates issued directly or indirectly by subordinate CAs below it in the CA hierarchy become invalid.”
Not "cannot be renewed". Invalid. Every certificate in the subtree, at once, on a date chosen years earlier by whoever accepted a default.
There are two ways to carry a CA past its expiry, and AWS states a preference: “We recommend replacing an expiring CA rather than reissuing its certificate because of the security advantages gained by rotating to a new key pair.” Reissuance, by contrast, “leaves all of the CA metadata in place and preserves the existing private and public keys.”
Then, a few paragraphs earlier, in a Note: “Private certificates issued through ACM cannot be renewed if you replace the CA. If you use ACM for issuance and renewal, you must re-issue the CA certificate to extend the lifetime of the CA.”
Both are correct and they point opposite ways. ACM-managed renewal — the thing that makes private certificates operationally tolerable at any scale — commits you to reissuance, which is the method AWS tells you not to prefer. The CA key you were advised to rotate is the one you cannot rotate without breaking renewal for everything that depends on it.
FixDecide at creation. If ACM renews your certificates, plan for reissuance, and get key rotation by standing up a new subordinate CA alongside rather than replacing the one ACM points at.
Two modes, and the gap is not subtle:
“$400 per private CA per month for general-purpose mode” against
“$50 per private CA per month for short-lived certificate mode”. Per certificate
it is $0.75 against $0.058 at low volume.
And the API reference names which one you get by not choosing:
“The default value is GENERAL_PURPOSE.”
At a thousand certificates a month that is $1,150 against $108 — a factor of about ten. The restriction in exchange is real: “Short-lived certificate validity is limited to seven days.” But a seven-day certificate is exactly what a Roles Anywhere workload or a service mesh wants, and that is a large share of what private CAs are actually used for.
FixWork out your longest required certificate lifetime before creating anything. Over seven days, buy general-purpose mode deliberately rather than by default.
The RevocationConfiguration parameter
“contains information to enable support for Online Certificate Status Protocol (OCSP),
certificate revocation list (CRL), both protocols, or neither. By default, both certificate
validation mechanisms are disabled.”
So a CA created without that block issues certificates that cannot be revoked in any way a client can discover. This is the gap #70 found, approached from the other end: there, AWS never calls your CRL distribution point; here, there may be no CRL for anything to call.
General-purpose mode is described as issuing certificates “that typically require a revocation mechanism”. Typically requiring one is not the same as having one.
It is fixable afterwards — UpdateCertificateAuthority
“Updates the status or configuration of a private certificate authority (CA)” and
takes a RevocationConfiguration, provided the CA
“must be in the ACTIVE or DISABLED
state”. What is not fixable is the certificates you already issued, which is the subject of
the next section.
Configure CRL, OCSP or both in the create call where you can — or choose short-lived mode and let expiry do the work, which is what it is for.
Architecture
The hierarchy is the part that is close to permanent, because its shape is written into every certificate it issues.
The hierarchy, and what it fixes permanently
“With AWS Private CA, you can create a hierarchy of certificate authorities with up to five levels… The root CA can have as many as four levels of subordinate CAs on each branch.”
The depth is enforced in the certificates themselves, through the basic constraints extension. A root
“needs maximum flexibility and does not include a path length constraint”, while
subordinates carry a pathLenConstraint that decrements down the tree. And the
enforcement happens at issuance:
“The IssueCertificate API will return an error if you attempt to
create a CA with a path length greater than or equal to the path length of its issuing CA
certificate.”
So the depth you can grow into later is decided by the constraint values you set now. An issuing CA minted
at PathLen0 can sign end-entity certificates and never another CA —
correct for an issuing CA, and also a choice that cannot be relaxed without replacing that CA and
everything beneath it.
Validity nests, and for CA certificates the comparison is strict
“A certificate managed by AWS Private CA must have a validity period shorter than or equal to the validity period of the CA that issued it. In other words, child CAs and end-entity certificates cannot outlive their parent certificates.”
For end-entity certificates that bound is inclusive. For CA certificates it is not:
“Attempting to use the IssueCertificate API to issue a CA
certificate with a validity period greater than or equal to the parent's CA
fails.” A subordinate cannot even match its parent's expiry — it must be strictly
shorter. Worth knowing before writing a module that sets both from one variable.
The defaults stack accordingly: ten years for a root, three years for a subordinate, 13 months (395 days) for an ACM-issued end-entity certificate. AWS's sizing rule is “two to five times the period of any child CA certificate or end-entity certificate it issues”, worked backwards from the leaf rather than forwards from the root.
Replacing a subordinate is routine — “Subordinate CA certificates can be changed without replacing the root CA certificate.” The root is not: “Changes to a root CA certificate affect the entire PKI… and require you to update all the dependent client operating system and browser trust stores.” That is because trust begins outside AWS entirely — “your organization's IT must ensure that each browser or system has previously added the private root CA to its trust store. Otherwise, the certification path cannot be validated, resulting in client errors.” Ten years is the default precisely so this becomes somebody else's problem, which is also why nobody will have rehearsed it.
Why This Architecture Holds Up
What it costs to operate, which is not what it costs to create
The monthly charge dominates at any volume a private PKI actually sees. From the published rates:
| Certificates / month | General-purpose | Short-lived | Ratio |
|---|---|---|---|
| 100 | $475.00 | $55.80 | 8.5× |
| 1,000 | $1,150.00 | $108.00 | 10.6× |
| 10,000 | $4,300.00 | $630.00 | 6.8× |
| 50,000 | $4,340.00 | $2,950.00 | 1.5× |
| ~74,400 | $4,364 | $4,364 | break-even |
| 100,000 | $4,390.00 | $5,850.00 | 0.75× |
The crossover sits near 74,400 certificates a month, where general-purpose mode's
$0.001 tier above 10,000 finally outweighs its eight-times-higher monthly
charge. Below that — which is every private PKI not issuing certificates to a manufactured device
fleet — short-lived mode is cheaper, by an order of magnitude through the middle of the range.
And notice what that $0.001 tier does to the general-purpose curve: past
10,000 certificates the bill barely moves. The decision is almost entirely about the fixed monthly charge
and almost not at all about volume.
Replacing a CA properly keeps the old one alive: “While disabled, the old CA supports revocation for old certificates issued from the CA… When the last certificate issued from the old CA expires, you can delete the old CA.” And the pricing page ties the end of charges to deletion rather than to disabling — “You are not charged for a private CA after you delete it”, with operation “pro-rated for partial months based on when you create and delete the CA.” With 395-day ACM certificates outstanding, that overlap runs about thirteen months, so one clean generational rotation of one general-purpose CA carries on the order of $5,200 of double-running on top of the new CA. That is the cost of doing it the recommended way, and it belongs in the plan rather than in a bill.
Revocation is updatable; the certificates already issued are not
The revocation configuration can be changed on a live CA. What cannot be changed is the distribution point written into every certificate issued before the change, and AWS spells out the consequence:
“If you update the S3BucketName of CrlConfiguration, you can
break revocation for existing certificates… AWS Private CA only writes CRLs to the
new S3 bucket. Certificates issued prior to this point will have the old S3 bucket name in your CRL
Distribution Point (CDP) extension, essentially breaking revocation. If you must update
the S3 bucket, you'll need to reissue old certificates to keep the revocation
working.”
So turning revocation on later is a real option, and moving it later is a trap: the CDP is baked into each certificate at issuance, so the population that most needs revoking — the old one — is exactly the population pointed at a bucket you no longer publish to. And nothing fails loudly. The CRL is being written; it is just being written somewhere no existing certificate names.
AWS gives the create-time remedy in the same paragraph:
“Alternatively, you can use a CustomCname in your CRL configuration
if you might need to change the S3 bucket name in the future.” A CNAME in the CDP means the
bucket behind it can move without invalidating anything. That is a one-line decision at creation that buys
you the ability to change your mind, which is rare in this service.
Deleting is not a safety valve either
“If you restore a deleted CA, you are charged for the time between deleting it and restoring it.” Deletion stops the meter only if it is permanent — a CA deleted during a cost review and restored when somebody notices the outage is billed for the gap anyway. And the free period is narrow and one-off: “no CA operation charge for the first 30 days for the first private CA created in the account in each Region”, which is enough to evaluate and not enough to pilot.
Two creation-time choices that bite later
UsageMode is set in the create call and is what the pricing follows, so the
$400-versus-$50 decision is made in the same API call that creates the CA, by a parameter that is
“Required: No”.
And the key-storage standard has a default that does not work everywhere:
“Default: FIPS_140_2_LEVEL_3_OR_HIGHER… Some AWS Regions don't support the default value.
When you create a CA in these Regions, you must use
CCPC_LEVEL_1_OR_HIGHER… If you don't, the operation returns an
InvalidArgsException…” A module that works in one Region
fails in another on a parameter nobody set.
The naming convention is a real control
Small, and it prevents a specific confusion:
“AWS recommends that you include a CA generation identifier in the names of CAs as
needed… This simple naming convention can help avoid confusion when both CAs are
unexpired.” The worked example in the documentation is a first-generation
Corporate Root CA followed by a Corporate Root CA G2.
During a succession both generations are unexpired and both are valid, and the only thing distinguishing them in a console list is a name you had to choose before you needed it.
Revocation has the same blast radius as expiry
“You revoke a CA by revoking its underlying certificate. This also effectively revokes all of the certificates issued by the CA.”
So the two bad days have identical scope: everything beneath the CA. That is the argument for more subordinates rather than fewer, each with a smaller population under it — the hierarchy is not an org chart, it is a blast-radius diagram. AWS's own guidance pulls the other way on depth (“Aim for a path length… no greater than necessary”, because each level adds validation time), so the shape to aim for is wide and shallow, not deep.
Key Architecture Decisions
| Decision | Choice | Reasoning |
|---|---|---|
| Usage mode | Short-lived unless a certificate must outlive 7 days | $50 against $400 a month; general-purpose is only cheaper above ~74,400 certificates a month. |
| Renewal strategy | Pick ACM-managed or key-rotating succession, at creation | ACM-issued certificates cannot be renewed if you replace the CA, so ACM commits you to reissuance. |
| Key rotation under ACM | New subordinate alongside, not replacement underneath | Gets a fresh key pair without invalidating ACM's renewal path for existing certificates. |
| Revocation | Configure CRL or OCSP in the create call | By default both are disabled, so certificates ship with no way to revoke them. Updatable later, but already-issued certificates keep the old distribution point. |
| CRL distribution point | CustomCname rather than a bare bucket name |
The CDP is written into each certificate at issuance; a CNAME lets the bucket move later without breaking revocation for existing certificates. |
| Root validity | Long, and write the trust-store rollout plan now | Changing it requires updating every dependent OS and browser trust store. |
| Subordinate validity | Strictly shorter than the parent, 2–5× the leaf | A CA certificate equal to its parent's validity fails at IssueCertificate. |
| Path length | PathLen0 for issuing CAs |
They cannot then mint further CAs; relaxing it later means replacing the CA. |
| Hierarchy shape | Wide and shallow — more subordinates, smaller populations | Expiry and revocation both take out the whole subtree; extra depth only adds validation time. |
| Naming | Generation suffix from the first CA onward | Both generations are unexpired and valid during a succession. |
| Key storage standard | Set explicitly in every module | The default is unsupported in some Regions and fails with InvalidArgsException. |
The two dates worth putting in a calendar
Not the root's expiry — that one is ten years out and will be somebody else's job. The two that matter are each subordinate's expiry minus the longest certificate lifetime it issues, because that is the last moment a replacement can start without leaving a gap, and the date the last certificate from a retired CA expires, because that is when the old CA can finally be deleted and the double billing stops.
AWS names the instrument for the second one: “You can generate an audit report for all of the certificates issued from the CA to confirm that all of the certificates issued have expired.” Nothing tells you the first one; it is arithmetic you have to do.
Closing Thought
A private CA is unusual among AWS resources in how much of it is settled by the
CreateCertificateAuthority call. Usage mode sets the bill for its whole life.
Path length decides how deep the hierarchy can grow. Validity sets a date on which everything beneath it
stops working. Those three need replacing the CA to change.
Revocation is the one that is genuinely updatable, and it still rewards getting right first time, because
what UpdateCertificateAuthority cannot reach is the distribution point already
written into every certificate you issued.
And replacing a CA is a planned migration rather than an impossibility: the cost is roughly thirteen months of double-running while the old CA stays disabled for revocation, plus the fact that private certificates previously issued through ACM cannot continue ACM-managed renewal from a replaced CA. Where that continued renewal matters, AWS's instruction is to reissue the CA certificate instead — which preserves the keys, and so forgoes the rotation that was the reason to replace it.
The pattern across this block is consistent by now. #36 was a boundary that bounds one of two paths. #70 was a trust anchor that anchors nothing without a condition. This one is a set of defaults that are each defensible and collectively expensive: general-purpose mode, no revocation, a ten-year root, and a distribution point that cannot be moved once the certificates naming it exist.
So it is the same rule in a different costume — read what the default does before accepting it. And here, specifically: write down the longest certificate lifetime you need before you create anything, because that one number picks your mode, your price, your revocation story and your succession plan all at once.
Security & Identity — KMS key policies and grants: why a grant is not a policy statement, what a grant can be created and retired by, and why the key policy is the one policy type that cannot be fixed from outside the key.
Official AWS Reference
- Manage the private CA lifecycle — the expiry cascade, validity nesting and defaults, and the replace-versus-reissue succession methods
- AWS Private CA pricing — monthly charges per mode, per-certificate tiers, and what deletion and restoration do to the bill
- CreateCertificateAuthority — UsageMode and its default, the revocation configuration default, and the Region-dependent key storage standard
- UpdateCertificateAuthority — what can be changed on a live CA, and why moving a CRL bucket breaks revocation for certificates already issued
- Design a CA hierarchy — the five-level limit, path length constraints, trust stores and certificate templates
Comments