BUG: Zone Detail by Name requires Zone List permission

There appears to be a missing API for Zones:

There is no way to retrieve Zone Details by name without also having the Zone List permission.

REPRO:

  1. Create a API Token with Zone.Zone:read and Zone.Zone Settings:read permissions for a specific resource.
  2. GET https://api.cloudflare.com/client/v4/zones?name=<specified resource>

RESULT:

  "success": false,
  "errors": [
    {
      "code": 0,
      "message": "Actor 'com.cloudflare.api.token.<redacted>' requires permission 'com.cloudflare.api.account.zone.list' to list zones"
    }
  ],
  "messages": [],
  "result": null
}

RESOLUTION:

Any one of the following:

  • Allow zone listings for zones that are included within a token’s permissions.
  • Enable zone detail retrieval by name.
  • Add an explicit Zone.Zone List permission to the API Token dashboard.

WORKAROUND:

Giving the API Token the Account.Account Settings:read permission appears to implicitly grant com.cloudflare.api.account.zone.list.

4 Likes

Thank you for posting this, I stumbled on the same issue.

I suspect the querystring (?name=*) is just a filter. Regardless of what filters you add, you need the corresponding permissions for the API endpoint, which is https://api.cloudflare.com/client/v4/zones.

1 Like

This workaround no longer seems to work.

Does anyone have any advice on how to resolve this issue?

1 Like

Thank you, digging internally for details.

1 Like

Sorry for the misinformation here.

I still think the issue describes in the original post should be resolved, but the workaround still works. The problem I’m having is the one described in Bug in list zones endpoint when using API token?.

1 Like

Any update on this? the workaround just broke and there dont seem to be any fixes yet.

EDIT:
new workaround is to give all perms, but that defeats the purpose

2 Likes

We’ve also encountered this issue while attempting to use Kubernetes cert-manager. The workaround does not appear to be functioning anymore.

If there’s anybody at Cloudflare that could give an ETA on this it would be much appreciated - using a global key rather than a token is a workaround that I’m not keen on at all :slight_smile:

2 Likes

Hello CloudFlare!

I have also encountered this bug. There seems to be no way to assign a list permission to the API token.

It would make use of CF API much safer with cert-manager.

Thank you!

1 Like

Just come across this same issue.

Neither of the workarounds seem to work.

Hi all,

I’ve Found the solution.

No, it’s not.

Even with this configuration, one still has to grant Zone Resources to at least All zones for an account (instead of the desirable Specific zone setting).

As such this still fail at restricting the token ability to modify all DNS records of all the zones of the account.

@cloonan Could you handle this? This is very serious issue as accessing single zone by name requires me to provide access token to all zones. The only thing I can do is to provide access to specific zone by ID, but then I’m forced to configure zones by their ID, not by theit name…

Hi everyone,

We just recently released a fix to this problem. Now if a token is granted read access to a specific zone, then you can filter the GET /zones API via the ?name= parameter. One caveat to be aware of is that this won’t work if using any other filters at the same time.

An example:
curl -X GET "https://api.cloudflare.com/client/v4/zones?name=example.com" \ -H "Authorization: Bearer <token>" \ -H "Content-Type:application/json"

Thanks for the patience here. Handling all the edge cases of the /zones call has been challenging. This API particular has many implications and combines lots of things which are challenging for supporting least privilege.

3 Likes

@ggalow Is it possible to fetch multiple zone ids by name, without making a call for each one? Something like https://api.cloudflare.com/client/v4/zones?name=example.com,bar.com,foo.com

Yup! It works exactly like that. Any zones that the token has ‘zone read’ privileges can be pulled like that.

@garret.galow this still seems like an issue.

How do you make it possible for the zones endpoint to list this one zone only:

This is what I get:

curl -X GET "https://api.cloudflare.com/client/v4/zones" \
     -H "Authorization: Bearer xxx" \
     -H "Content-Type: application/json"
		 
{"success":false,"errors":[{"code":0,"message":"Actor 'com.cloudflare.api.token.xxx' requires permission 'com.cloudflare.api.account.zone.list' to list zones"}],"messages":[],"result":null}

I feel like if I set that zone to be editable by a specific token, that zones list should show that one and only zone. Is that possible?

Hey @samuel1, the permissions you’ve set are correct, but in order to access a single zone, you need to specify the zone name in the request, ie. use https://api.cloudflare.com/client/v4/zones?name=oriontransfer.co.nz. Also note this must be the root zone name, not the www(or other) subdomains.

If you want to use the zones endpoint directly without providing a name, you need to allow the token access to all zones. That error mentioning the com.cloudflare.api.account.zone.list permission will show for a variety of reasons which can make error handling difficult, but unfortunately this is just the way Cloudflare have implemented this endpoint.

Thanks for your reply.

I maintain a DNS update script, and it has a guided walkthrough. The script presents the user a list of domains which dynamic DNS can be set up for, an thus there is no way for the script to know ahead of time what domain names are available. Therefore providing the name parameter is not possible. The only way I can see to work around this is to give all permissions on the key and then restrict them after the setup is complete, which frankly seems a bit insecure. I don’t see why the zones endpoint couldn’t provide a list of all zones available for the specific token. That would make the most sense, from the POV of an outsider.

Yeah, CF’s implementation is certainly not ideal. It took quite some back and forth to get it to where it is now - you couldn’t access the endpoint at all with anything but all zone access before. For your script, there’s a couple of workarounds depending on usability requirements:

  1. Like you say, first get a token with all zone access, then restrict it after the fact
  2. Get the user to enter the domain name, or even the Zone ID(bottom right of the zone’s overview page in CF). For bulk operations this is obviously less practical.
  3. Ask for the user’s global key and list all the zones that way, then use it to make a token automatically with this endpoint. You can then store the token for future operations without needing the global key. I have not used this method, but it looks worth investigating at least.