Skip to content

Conversation

@colin-stubbs
Copy link

@colin-stubbs colin-stubbs commented Aug 20, 2025

Adds support for CAA records to resolve issue #16.

Includes a parsing function to validate that the data portion of the record conforms to RFC8659 when static non-templated values are specified.

When given CAA records with invalid static data content or non-RFC conformant values it will error,

# flags > 255
user@box domain-connect-templates % dc-template-linter goodroots.work.caa_management.json
2025-08-20T16:05:11+10:00 ERR code=DCTL1015 dctl_note="invalid value" flags=256 groupid= record=2 template=goodroots.work.caa_management.json type=CAA
user@box domain-connect-templates %

# flags less than 0
user@box domain-connect-templates % dc-template-linter goodroots.work.caa_management.json
2025-08-20T16:05:23+10:00 ERR code=DCTL1015 dctl_note="invalid value" flags=-1 groupid= record=2 template=goodroots.work.caa_management.json type=CAA
user@box domain-connect-templates %

# invalid tag format
user@box domain-connect-templates % dc-template-linter goodroots.work.caa_management.json
2025-08-20T16:26:46+10:00 ERR code=DCTL1015 dctl_note="invalid value" groupid= record=1 tag=Issue template=goodroots.work.caa_management.json type=CAA
user@box domain-connect-templates % 

# unsupport iodef URL type
user@box domain-connect-templates % dc-template-linter goodroots.work.caa_management.json
2025-08-20T16:05:46+10:00 ERR code=DCTL1015 data="128 iodef \"mongodb://mongo\"" dctl_note="invalid value" groupid= record=2 template=goodroots.work.caa_management.json type=CAA
user@box domain-connect-templates %

# invalid iodef URL
user@box domain-connect-templates % dc-template-linter goodroots.work.caa_management.json
2025-08-20T16:06:32+10:00 ERR code=DCTL1015 data="0 iodef \"asdf\"" dctl_note="invalid value" groupid= record=1 template=goodroots.work.caa_management.json type=CAA
user@box domain-connect-templates %

# invalid iodef URL
user@box domain-connect-templates % dc-template-linter goodroots.work.caa_management.json
2025-08-20T16:06:40+10:00 ERR code=DCTL1015 data="0 iodef \"asdf.com\"" dctl_note="invalid value" groupid= record=1 template=goodroots.work.caa_management.json type=CAA
user@box domain-connect-templates %

# empty value
user@box domain-connect-templates % dc-template-linter goodroots.work.caa_management.json
2025-08-20T16:06:28+10:00 ERR code=DCTL1015 data="0 iodef \"\"" dctl_note="invalid value" groupid= record=1 template=goodroots.work.caa_management.json type=CAA
user@box domain-connect-templates %

# empty value
user@box domain-connect-templates % dc-template-linter goodroots.work.caa_management.json
2025-08-20T16:07:19+10:00 ERR code=DCTL1015 data="0 issue \"\"" dctl_note="invalid value" groupid= record=1 template=goodroots.work.caa_management.json type=CAA
2025-08-20T16:07:19+10:00 ERR code=DCTL1015 data="128 issuewild \"\"" dctl_note="invalid value" groupid= record=2 template=goodroots.work.caa_management.json type=CAA
user@box domain-connect-templates %

# missing one or more double quotes around value string
user@box domain-connect-templates % dc-template-linter goodroots.work.caa_management.json
2025-08-20T16:07:32+10:00 ERR code=DCTL1015 data="0 issue letsencrypt.org\"" dctl_note="invalid value" groupid= record=1 template=goodroots.work.caa_management.json type=CAA
2025-08-20T16:07:32+10:00 ERR code=DCTL1015 data="128 issuewild letsencrypt.org\"" dctl_note="invalid value" groupid= record=2 template=goodroots.work.caa_management.json type=CAA
user@box domain-connect-templates %

github-merge-queue bot pushed a commit to Domain-Connect/Templates that referenced this pull request Aug 21, 2025
# Description

Add the Good Roots Work Domain Connect template to support programmatic
management of DNS CAA policy records.

## Type of change

Please mark options that are relevant.

- [X] New template
- [ ] Bug fix (non-breaking change which fixes an issue in the template)
- [ ] New feature (non-breaking change which adds functionality to the
template)
- [ ] Breaking change (fix or feature that would cause existing template
behavior to be not backward compatible)

# How Has This Been Tested?

Please mark the following checks done
- [X] Schema validated using JSON Schema
[template.schema](./template.schema)
- [X] Template functionality checked using [Online
Editor](https://domainconnect.paulonet.eu/dc/free/templateedit)
- [X] Template is checked using [template
linter](https://github.com/Domain-Connect/dc-template-linter)
- [X] Template file name follows the pattern
`<providerId>.<serviceId>.json`

*NOTE*: Despite all of the Domain Connect documentation describing CAA
record support the [template
linter](https://github.com/Domain-Connect/dc-template-linter) did not
support CAA records yet. I have added support via
[PR#17](Domain-Connect/dc-template-linter#17)

dc-template-linter with added CAA support has no issues with our
template,

```
user@box domain-connect-templates % dc-template-linter goodroots.work.caa_management.json
user@box domain-connect-templates % 
```

# Example variable values

A set of examples whereby a registered domain (example.com) wishes to,
by default, only have certificates issued by DigiCert and would like to
receive issuance violation notifications via [email protected]. Yet
they have delegated authority to issue a certificate for a specific
subdomain name (sub.example.com) to Let's Encrypt only.

Example 1, apex domain, non-critical issue property with additional
parameters,

```
host: @
flags: 0
tag: issue
value: "digicert.com; cansignhttpexchanges=yes"
```

Example 2, apex domain, critical issuewild property with additional
parameters,
```
host: @
flags: 128
tag: issuewild
value: "digicert.com; cansignhttpexchanges=yes"
```

Example 3, apex domain, non-critical iodef property with additional
parameters,

```
host: @
flags: 0
tag: iodef
value: "mailto:[email protected]"
```

Example 4, sub domain, critical issue property,

```
host: sub
flags: 128
tag: issue
value: "letsencrypt.org"
```

Results from https://domainconnect.paulonet.eu/dc/free/templateedit

*NOTE*: If using https://domainconnect.paulonet.eu/dc/free/templateedit
it doesn't currently support CAA records at present, so this was
generated as TXT records as they have the same basic format. TXT was
substituted to CAA afterwards.

```
{
  "providerId": "goodroots.work",
  "providerName": "Good Roots Work",
  "serviceId": "caa_management",
  "serviceName": "CAA Policy Management",
  "version": 1,
  "logoUrl": "https://goodroots.work/goodroots.svg",
  "description": "Provides tooling to manage error free RFC compliant best practice CAA policy records for a domain, subdomain or specific hostname.",
  "variableDescription": "%flags%: flags for the CAA record, typically 0, or 128 to indicate critical; %tag%: tag for the CAA record; %value%: value for the CAA record;",
  "syncBlock": false,
  "syncPubKeyDomain": "caa.goodroots.work",
  "multiInstance": false,
  "warnPhishing": false,
  "hostRequired": true,
  "records": [
    {
      "type": "CAA",
      "host": "@",
      "data": "%flags% %tag% \"%value%\"",
      "ttl": 300
    }
  ],
  "testData": {
    "Apex-issue": {
      "variables": {
        "domain": "example.com",
        "host": "@",
        "flags": "0",
        "tag": "issue",
        "value": "digicert.com; cansignhttpexchanges=yes"
      },
      "results": [
        {
          "type": "CAA",
          "name": "@",
          "ttl": 300,
          "data": "0 issue \"digicert.com; cansignhttpexchanges=yes\""
        }
      ]
    },
    "Apex-issuewild-Critical": {
      "variables": {
        "domain": "example.com",
        "host": "@",
        "flags": "128",
        "tag": "issuewild",
        "value": "digicert.com; cansignhttpexchanges=yes"
      },
      "results": [
        {
          "type": "CAA",
          "name": "@",
          "ttl": 300,
          "data": "128 issuewild \"digicert.com; cansignhttpexchanges=yes\""
        }
      ]
    },
    "Apex-iodef": {
      "variables": {
        "domain": "example.com",
        "host": "@",
        "flags": "0",
        "tag": "iodef",
        "value": "mailto:[email protected]"
      },
      "results": [
        {
          "type": "CAA",
          "name": "@",
          "ttl": 300,
          "data": "0 iodef \"mailto:[email protected]\""
        }
      ]
    },
    "Sub-issue": {
      "variables": {
        "domain": "example.com",
        "host": "sub",
        "flags": "0",
        "tag": "issue",
        "value": "letsencrypt.org"
      },
      "results": [
        {
          "type": "CAA",
          "name": "sub",
          "ttl": 300,
          "data": "0 issue \"letsencrypt.org\""
        }
      ]
    }
  }
}  
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant