# Create an intermediate certificate authority

To create an intermediate CA, generate a key and CSR for it, then sign that CSR with your root using extensions that mark the result as a CA — `basicConstraints=critical,CA:TRUE,pathlen:0` and `keyUsage=critical,keyCertSign,cRLSign`. The `pathlen:0` constraint means the intermediate may issue end-entity certificates but may not create further CAs beneath itself, which limits the damage if its key is exposed. Once it exists, the root key can go back offline and the intermediate does all day-to-day signing.

Source: https://certguru.io/openssl/create-intermediate-ca/
Last updated: 2026-08-19
Commands verified against OpenSSL 3.5.7.

---

## Step 1 — the intermediate's key

```bash
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -aes-256-cbc -out intermediate.key
```

```bash
chmod 400 intermediate.key
```

## Step 2 — a CSR for it

```bash
openssl req -new -key intermediate.key -out intermediate.csr \
  -subj "/C=US/O=Example Inc/CN=Example Inc Intermediate CA"
```

## Step 3 — the CA extensions

Signing an intermediate is signing a CA, so the extensions differ from a server certificate:

*intermediate-ext.cnf*

```ini
basicConstraints       = critical,CA:TRUE,pathlen:0
keyUsage               = critical,digitalSignature,keyCertSign,cRLSign
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid:always,issuer
```

| Placeholder | What to put there |
| --- | --- |
| `CA:TRUE` | This certificate may sign other certificates. |
| `pathlen:0` | It may not create further CAs beneath itself. |
| `keyCertSign, cRLSign` | Permits signing certificates and revocation lists. |
| `authorityKeyIdentifier` | Links back to the root so clients can build the chain. |

## Step 4 — sign it with the root

```bash
openssl x509 -req -in intermediate.csr \
  -CA root-ca.crt -CAkey root-ca.key -CAcreateserial \
  -out intermediate.crt -days 1825 -sha256 \
  -extfile intermediate-ext.cnf
```

> **Now put the root key away**
>
> This is the last time the root key is needed until the intermediate expires or must be replaced.
>   Move it back offline — that is the entire reason for going through this.

## Step 5 — verify

```bash
openssl verify -CAfile root-ca.crt intermediate.crt
```

Expected output:

```
intermediate.crt: OK
```

```bash
openssl x509 -in intermediate.crt -noout -subject -issuer -ext basicConstraints -ext keyUsage
```

Expected output:

```
subject=C = US, O = Example Inc, CN = Example Inc Intermediate CA
issuer=C = US, O = Example Inc, CN = Example Inc Root CA
X509v3 Basic Constraints: critical
    CA:TRUE, pathlen:0
X509v3 Key Usage: critical
    Digital Signature, Certificate Sign, CRL Sign
```

## Step 6 — issue from the intermediate

```bash
openssl x509 -req -in server.csr \
  -CA intermediate.crt -CAkey intermediate.key -CAcreateserial \
  -out server.crt -days 397 -sha256 \
  -extfile server-ext.cnf
```

Then verify the full path, with the root as anchor and the intermediate as an untrusted link:

```bash
openssl verify -CAfile root-ca.crt -untrusted intermediate.crt server.crt
```

Expected output:

```
server.crt: OK
```

## Step 7 — the chain file

```bash
cat server.crt intermediate.crt > fullchain.crt
```

Leaf first, intermediate second, root omitted. See
[certificate chains](/concepts/certificate-chain/).

## Constraining the intermediate to your own domains

Worth doing. Without it, a leaked intermediate can issue a certificate for any hostname, and every
machine trusting your root will accept it:

*Add to intermediate-ext.cnf*

```ini
nameConstraints = critical,permitted;DNS:.example.com,permitted;DNS:.internal
```

> **Name constraints are enforced unevenly**
>
> Support is good in OpenSSL and modern browsers and patchy in older embedded stacks. Treat it as
>   defence in depth rather than as the only thing standing between a leaked key and a problem.


## Frequently asked questions

### What does pathlen:0 do?

It caps how many further CA certificates may appear below this one. `pathlen:0` means none — the intermediate can issue server and client certificates but cannot create another CA. It limits the blast radius if the intermediate key is exposed.

### Do I need an intermediate for an internal CA?

Only if you will actually keep the root offline. The entire benefit is that the root key is not on a running machine. If the root key is going to sit on the same server anyway, the extra layer adds complexity and buys nothing.

### Which certificates does the server send?

The leaf and the intermediate. Not the root — clients that trust your CA already have it installed.

### Can an intermediate issue a certificate for a name outside my organisation?

By default yes, which is why `nameConstraints` exists. Adding `nameConstraints=critical,permitted;DNS:.example.com` restricts it to your own domains, so a leaked intermediate cannot be used to impersonate anyone else.


## References

- [openssl-ca(1)](https://docs.openssl.org/3.5/man1/openssl-ca/) — the CA command and its configuration file
- [RFC 5280: X.509 and CRL profile](https://www.rfc-editor.org/rfc/rfc5280) — the specification every field on a certificate comes from

## Related pages

- https://certguru.io/openssl/create-root-ca/
- https://certguru.io/openssl/sign-csr-with-ca/
- https://certguru.io/concepts/root-vs-intermediate-ca/
- https://certguru.io/concepts/certificate-chain/
- https://certguru.io/openssl/verify-certificate-chain/

--
CertGuru — https://certguru.io
