dnscontrol icon indicating copy to clipboard operation
dnscontrol copied to clipboard

1Password 'op' does not seem to work, both CNR, CLOUDFLAREAPI

Open mejofi opened this issue 6 months ago • 11 comments

NOTE: Have a general question? You'll get a better response on the dnscontrol-discuss email list!

Describe the bug According to the documentation, we should be able to use the 1Password op CLI tool to retrieve credentials via the op://vault/entry/field syntax. I have been unable to get this to work reliably. For CNR it fails on both apilogin and apipassword, while for CLOUDFLAREAPI it works for accountid, but fails for apitoken

To Reproduce With the following creds.json;

{
	"CNR": {
		"TYPE": "CNR",
		"apilogin": "op://Employee/rrpproxy/username",
		"apipassword": "op://Employee/rrpproxy/password",
		"apientity": "LIVE",
		"debugmode": "0"
	},
	"CF_MAIN": {
		"TYPE": "CLOUDFLAREAPI",
		"accountid": "op://Employee/dnscontrol-cloudflare-main/username",
		"apitoken": "op://Employee/dnscontrol-cloudflare-main/password"
	}
}

CLOUDFLAREAPI fails with the following error;

INFO#1: zoneList failed for "CF_MAIN": failed fetching domain list from cloudflare(""): Invalid request headers (6003)

unless the apitoken is hardcoded. Requesting the same value via op read works just fine.

CNR fails with the following error;

INFO#1: zoneList failed for "CNR": Error while QueryDNSZoneList "Basic". [530 Authentication failed]

unless both values are hardcoded. Requesting the value via op read works fine, just like above.

Expected behavior Retrieve the credentials as expected and use them, instead of causing authentication errors.

DNS Provider CNR, CLOUDFLAREAPI

Additional context 1Password CLI 2.31.1 - ~/bin/op DNSControl version 4.21.0 - ~/bin/dnscontrol

It happened with older versions as well, so perhaps I am missing something obvious, or there's a discrepancy between what is documented, and how it works in practice?

mejofi avatar Jun 17 '25 13:06 mejofi

Running check-creds in debug mode does not seem to enlighten either;

% dnscontrol --debug check-creds CF_MAIN CLOUDFLAREAPI
failed GetZone LZ: failed fetching domain list from cloudflare(""): Invalid request headers (6003)

% dnscontrol --debug check-creds CNR CNR              
failed GetZone LZ: Error while QueryDNSZoneList "Basic". [530 Authentication failed]

mejofi avatar Jun 17 '25 13:06 mejofi

CC @plttn who wrote the 1password integration

tlimoncelli avatar Jun 17 '25 15:06 tlimoncelli

The file that you listed as creds.json should be creds.json.tpl.

Then this command will read the .tpl file and generate creds.json:

dnscontrol preview --creds '!op inject -i creds.json.tpl'

tlimoncelli avatar Jun 17 '25 15:06 tlimoncelli

Looking at the docs, I see a number of ways we could improve them:

  • Use the .tpl filenames in the docs. Listing creds.json is misleading.
  • Suggest this link for help with inject: https://developer.1password.com/docs/cli/reference/commands/inject/
  • Explain that DNSControl doesn't have code specific to 1password; the op CLI command does all the work.

tlimoncelli avatar Jun 17 '25 15:06 tlimoncelli

@tlimoncelli said everything I would have said. Additionally, I've tweaked the way I do it slightly since those docs were written as I've discovered more tooling:

My .env file:

DESEC_AUTH_TOKEN="op://Secrets/deSEC DNSControl/credential"
PORKBUN_API_KEY="op://Secrets/Porkbun DNSControl/username"
PORKBUN_SECRET_KEY="op://Secrets/Porkbun DNSControl/credential"
CLOUDFLARE_USER_ID="op://Secrets/Cloudflare DNSControl/username"
CLOUDFLARE_API_KEY="op://Secrets/Cloudflare DNSControl/credential"

My creds.json (not creds.json.tpl):

{
    "bind": {
        "TYPE": "BIND"
    },
    "desec": {
        "TYPE": "DESEC",
        "auth-token": "$DESEC_AUTH_TOKEN"
    },
    "porkbun": {
        "TYPE": "PORKBUN",
        "api_key": "$PORKBUN_API_KEY",
        "secret_key": "$PORKBUN_SECRET_KEY"
    },
    "cloudflare": {
        "TYPE": "CLOUDFLAREAPI",
        "apitoken": "$CLOUDFLARE_API_KEY",
        "accountid": "$CLOUDFLARE_EMAIL"
    }
}

I then run using op run -- dnscontrol preview or op run -- dnscontrol push. By default, 1Password CLI won't load any env files, but I have mise set to load the environment variables defined from the env file, so op run works as expected.

Without mise, it'd look something like op run --env-file=.env -- dnscontrol preview.

plttn avatar Jun 17 '25 15:06 plttn

@plttn Jack, I see benefits to both ways of doing it. Would you please update the docs to include both methods?

CC: @cafferata our documentation guru.

tlimoncelli avatar Jun 17 '25 16:06 tlimoncelli

Ah, more complicated than it appears at first, then 😄

I am curious, though; why does it work for accountid in CLOUDFLAREAPI, but not for apitoken? It seems like either both should work, or neither of them, but instead it sort of works, but in an unpredictable manner?

mejofi avatar Jun 17 '25 20:06 mejofi

Other question: have you updated the name of the field in 1Password?

Image

You can copy the correct secret reference from the field in the 1Password app.

plttn avatar Jun 17 '25 20:06 plttn

Other question: have you updated the name of the field in 1Password?

Image

You can copy the correct secret reference from the field in the 1Password app.

Tested with copied secret references, yes. Makes no difference.

mejofi avatar Jun 17 '25 20:06 mejofi

Hmm, alright, last quick question: If you run op inject -i creds.json, does the output file have all the fields injected as expected (matching your hardcoded one)?

plttn avatar Jun 17 '25 21:06 plttn

Hmm, alright, last quick question: If you run op inject -i creds.json, does the output file have all the fields injected as expected (matching your hardcoded one)?

Yes, that works as expected.

I have created a wrapper that maps dnscontrol to op run --env-file=.env -- dnscontrol, so my immediate need has been met, but the 'some fields work, some fields do not' remains an odd quirk.

Thanks for the help so far! 🙂

mejofi avatar Jun 17 '25 21:06 mejofi

Glad it works!

tlimoncelli avatar Jul 25 '25 16:07 tlimoncelli