1Password 'op' does not seem to work, both CNR, CLOUDFLAREAPI
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?
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]
CC @plttn who wrote the 1password integration
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'
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 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 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.
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?
Other question: have you updated the name of the field in 1Password?
You can copy the correct secret reference from the field in the 1Password app.
Other question: have you updated the name of the field in 1Password?
You can copy the correct secret reference from the field in the 1Password app.
Tested with copied secret references, yes. Makes no difference.
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)?
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! 🙂
Glad it works!