Altinn / Altinn/altinn-platform
Add CAA records to altinn.no (currently none — any CA may issue)
- Dominant language
- Go
- Stars
- 13
- Forks
- 7
- Avg merge
- 19h 21m
- Merged PRs (30d)
- 76
Description
## Summary
`altinn.no` has **no CAA records**. Any publicly trusted CA in the world may issue a certificate for `altinn.no` or any of its subdomains, and we get no notification when someone tries.
This is out of line with our own practice elsewhere — `altinn.cloud`, `altinn.studio` and `digdir.no` all publish CAA. `altinn.no` appears to have simply been missed, along with `altinncdn.no`, `altinn.app` and `ai-dev.no`.
```
$ dig +short CAA altinn.no
$ dig +short CAA altinn.cloud
0 issue "letsencrypt.org"
0 issuewild "ssl.com"
0 iodef "mailto:sikkerhet@digdir.no"
... (11 records)
$ dig +short CAA digdir.no
0 issue "buypass.no"
0 iodef "mailto:drift@digdir.no"
... (6 records)
```
## Why it matters
CAA is defence-in-depth against mis-issuance: a CA that is compromised, socially engineered, or simply tricked by a domain-validation weakness will refuse to issue if CAA doesn't authorise it. Without CAA there is nothing at the DNS layer stopping any CA from issuing for our highest-value domain.
It also compounds any domain-validation exposure we have. Anyone who gains control of an endpoint we point DNS at can complete an ACME HTTP-01 challenge and obtain a valid, publicly trusted certificate for an `altinn.no` hostname — which makes phishing against citizens and businesses far more convincing. CAA narrows which CAs can be used for that, and `iodef` gives us a signal when it is attempted.
Related: #3907 (dangling DNS records for decommissioned clusters) is exactly the class of exposure this mitigates. The two issues are independent, but CAA reduces the blast radius of that whole category.
## Which CAs we actually use
From Certificate Transparency for `altinn.no` + subdomains, last 12 months (96 certificates):
| CA | Certs |
|---|---|
| Google Trust Services (`WE1`, `WR1`) | 63 |
| DigiCert (`GeoTrust TLS RSA CA G1`) | 15 |
| Buypass (`Buypass Class 2 CA 2`) | 14 |
| Let's Encrypt (`YE1`, `YE2`, `YR1`) | 4 |
Wildcards in active use include `*.altinn.no` (Buypass), `*.apps.altinn.no` and `*.apps.tt02.altinn.no` — so `issuewild` must be set, not just `issue`.
## Proposed record set
Modelled on the existing `altinn.cloud` set:
```
altinn.no. 3600 IN CAA 0 issue "pki.goog; cansignhttpexchanges=yes"
altinn.no. 3600 IN CAA 0 issue "digicert.com"
altinn.no. 3600 IN CAA 0 issue "buypass.com"
altinn.no. 3600 IN CAA 0 issue "buypass.no"
altinn.no. 3600 IN CAA 0 issue "letsencrypt.org"
altinn.no. 3600 IN CAA 0 issuewild "pki.goog; cansignhttpexchanges=yes"
altinn.no. 3600 IN CAA 0 issuewild "digicert.com"
altinn.no. 3600 IN CAA 0 issuewild "buypass.com"
altinn.no. 3600 IN CAA 0 issuewild "buypass.no"
altinn.no. 3600 IN CAA 0 issuewild "letsencrypt.org"
altinn.no. 3600 IN CAA 0 iodef "mailto:sikkerhet@digdir.no"
```
## ⚠️ Before applying
CAA is evaluated at issuance time, so this will not affect existing certificates — but **any renewal path using a CA not on the list will start failing**. The 12-month CT window above is evidence, not proof of completeness. Verify against actual issuance paths first:
- Azure Front Door / CDN managed certificates (DigiCert or Google Trust Services depending on profile)
- Azure App Service and APIM managed certificates
- Key Vault certificate issuers
- cert-manager / ACME clients in the AKS clusters
- Any manually procured certificates with a longer renewal cycle than 12 months
## Actions
- [ ] Enumerate all certificate issuance paths for `altinn.no` and confirm the CA list is complete
- [ ] Add CAA records to the `altinn.no` Cloudflare zone
- [ ] Confirm `sikkerhet@digdir.no` is the right `iodef` destination and that reports there are actually monitored
- [ ] Apply the same treatment to `altinncdn.no`, `altinn.app` and `ai-dev.no`, which also have no CAA
- [ ] Consider adding a CAA presence check to whatever we use for external attack-surface monitoring
## Note on disclosure
Filed with full detail deliberately: the absence of CAA is a single `dig` query away for anyone, and there is no exploitable target list here — unlike #3907, which is redacted.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.