Dedyn.io requires more permissions than regular desec API?

Hey!

I recently started switching over to desec.io.

Right now I’m trying to debug an issue with dyndns setup, and especially using ddclient with dedyn.io.

I have a token that can perform this action without issues (anonymized domain names with foo/bar/baz/quux so that the number of dots at least is visible):

myuser$ curl -X PATCH https://desec.io/api/v1/domains/baz.quux/rrsets/foo.bar/A/ --header "Authorization: Token $DESEC_TOKEN" --header "Content-Type: application/json" --data @- <<< '{"records": ["1.2.3.4"]}'
{"created":"2025-01-29T23:29:23.284649Z","domain":"baz.quux","subname":"foo.bar","name":"foo.bar.baz.quux.","records":["1.2.3.4"],"ttl":60,"type":"A","touched":"2025-01-30T15:46:47.179278Z"}

Based on this, I’m assuming that my token has the correct permissions.

However, when I try using dedyn.io (so that it works from ddclient), I get the following error:

myuser$ curl 'https://update.dedyn.io/?hostname=foo.bar.baz.quux&ip=4.3.2.1' --header "Authorization: Token $DESEC_TOKEN"
Insufficient token permissions.

This being said, if I run the same command with a token with full access rights, it does work correctly:

otheruser$ curl 'https://update.dedyn.io/?hostname=foo.bar.baz.quux&ip=4.3.2.1' --header "Authorization: Token $TOKEN"
good

Similarly, if I try with basic auth (that AFAIU is the thing ddclient is using), I get the same results:

myuser$ curl 'https://update.dedyn.io/?hostname=foo.bar.baz.quux&ip=4.3.2.1' -u foo.bar.baz.quux:$DESEC_TOKEN
Insufficient token permissions.
otheruser$ curl 'https://update.dedyn.io/?hostname=foo.bar.baz.quux&ip=4.3.2.1' -u foo.bar.baz.quux:$TOKEN
good

Is this a known limitation of desec’s dyndns service, a bug that is planned to be fixed, or am I misusing the APIs?

For full completeness, here is the full token policy (I checked it’s the correct token by toggling the “manage tokens” permissions and checking access to the desec API changed):
(Note the example.org is another DNS, not related to the baz.quux domain)

[
    {
        "domain": null,
        "id": "[censored]",
        "perm_write": false,
        "subname": null,
        "type": null
    },
    {
        "domain": "baz.quux",
        "id": "[censored]",
        "perm_write": true,
        "subname": "foo.bar",
        "type": "A"
    },
    {
        "domain": "example.org",
        "id": "[censored]",
        "perm_write": true,
        "subname": "_acme-challenge.test",
        "type": "TXT"
    }
]

Hi Ekleog,

It’s neither a limitation nor a bug :wink:

The dynDNS update interface will also touch your AAAA records (removing them if you’re connecting via IPv4 and not supplying an IPv6 address in the URL, see docs). Therefore, write permission for RRset type AAAA is also required.

If you don’t want to touch your IPv6 address (including if you don’t have an AAAA RRset), you can pass myipv6=preserve, in which case IPv6 processing does not happen and you don’t need that permission.

Stay secure,
Peter

1 Like

You’re right, that was exactly my problem. Thank you very much! :smiley: