Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Empty condition block in cloudflare_api_token #897

Closed
dsalaza4 opened this issue Dec 18, 2020 · 12 comments
Closed

Empty condition block in cloudflare_api_token #897

dsalaza4 opened this issue Dec 18, 2020 · 12 comments
Labels
kind/bug Categorizes issue or PR as related to a bug. triage/accepted Indicates an issue or PR is ready to be actively worked on.

Comments

@dsalaza4
Copy link

Terraform version

$ terraform -v
Terraform v0.13.1

Affected resource(s)

cloudflare_api_token

Terraform configuration files

resource "cloudflare_api_token" "token_terraform" {
  name = "token_terraform"

  policy {
    effect = "allow"
    permission_groups = [
      data.cloudflare_api_token_permission_groups.all.permissions["DNS Read"],
    ]
    resources = {
      "com.cloudflare.api.account.zone.*" = "*",
    }
  }
}

Expected behavior

cloudflare_api_token should not have a condition block when not provided in terraform.

Actual behavior

When I create a cloudflare_api_token and try to use it, I get the following error:

$ curl -X GET "https://api.cloudflare.com/client/v4/zones/<zone_id>" \
>      -H "Authorization: Bearer <token_terraform>" \
>      -H "Content-Type: application/json"
{"success":false,"errors":[{"code":9109,"message":"Cannot use the access token from location: <my-ip>"}],"messages":[],"result":null}

When I manually create a token with the same permissions, the request works just fine:

curl -X GET "https://api.cloudflare.com/client/v4/zones/<zone_id>" \
     -H "Authorization: Bearer <token_manual>" \
     -H "Content-Type: application/json"
TOKEN WORKS!

When listing both tokens, I notice that the only difference between them is an empty condition block in token_terraform:

{
  "result":[
    {
      "id":"<id>",
      "name":"token_terraform",
      "status":"active",
      "issued_on":"2020-12-17T22:45:33Z",
      "modified_on":"2020-12-18T18:59:55Z",
      "last_used_on":null,
      "policies":[
        {
          "id":"5cd1bb2a81a14d4e95b6b2ebc3be32f2",
          "effect":"allow",
          "resources":{
            "com.cloudflare.api.account.zone.*":"*"
          },
          "permission_groups":[
            {
              "id":"82e64a83756745bbbb1c9c2701bf816b",
              "name":"DNS Read"
            }
          ]
        }
      ],
      "condition":{
        "request.ip":{
          "in":[
            
          ],
          "not_in":[
            
          ]
        }
      }
    },
    {
      "id":"<id>",
      "name":"token_manual",
      "status":"active",
      "issued_on":"2020-12-17T21:22:33Z",
      "modified_on":"2020-12-17T21:24:44Z",
      "last_used_on":"2020-12-18T19:00:56Z",
      "policies":[
        {
          "id":"8ece580c15a34b4da2afbc1702842917",
          "effect":"allow",
          "resources":{
            "com.cloudflare.api.account.zone.*":"*"
          },
          "permission_groups":[
            {
              "id":"82e64a83756745bbbb1c9c2701bf816b",
              "name":"DNS Read"
            }
          ]
        }
      ]
    },
...

Steps to reproduce

  1. Create token via terraform.
  2. Try to use it.
  3. You'll get a Cannot use the access token from location: <your-ip> error.
  4. Manually create a token with the same permissions.
  5. Use it.
  6. It will work just fine.

Community note

  • Please vote on this issue by adding a 👍 reaction
    to the original issue to help the community and maintainers prioritize this request
  • If you are interested in working on this issue or have submitted a pull
    request, please leave a comment
@dsalaza4 dsalaza4 added kind/bug Categorizes issue or PR as related to a bug. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. labels Dec 18, 2020
@dsalaza4
Copy link
Author

It looks like this issue goes deeper than I initially thought. For some reason, when editing the condition block from token_terraform by doing:

curl -X PUT "https://api.cloudflare.com/client/v4/user/tokens/<token_terraform_id>" \
     -H "X-Auth-Email: <email>" \
     -H "X-Auth-Key: <token>" \
     -H "Content-Type: application/json" \
     --data '{"id":"<token_terraform_id>","name":"token_terraform","status":"active","policies":[{"id":"5cd1bb2a81a14d4e95b6b2ebc3be32f2","effect":"allow","resources":{"com.cloudflare.api.account.zone.*":"*"},"permission_groups":[{"id":"82e64a83756745bbbb1c9c2701bf816b","name":"DNS Read"}]}], "condition": ""}'

I still get the 9109 error code, even when the api lists the token with no condition block at all:

{
  "result":{
    "id":"<token_terraform_id>",
    "name":"token_terraform",
    "status":"active",
    "issued_on":"2020-12-17T22:45:33Z",
    "modified_on":"2020-12-18T19:48:59Z",
    "last_used_on":null,
    "policies":[
      {
        "id":"5cd1bb2a81a14d4e95b6b2ebc3be32f2",
        "effect":"allow",
        "resources":{
          "com.cloudflare.api.account.zone.*":"*"
        },
        "permission_groups":[
          {
            "id":"82e64a83756745bbbb1c9c2701bf816b",
            "name":"DNS Read"
          }
        ]
      }
    ]
  },
...

I am not sure if by doing "condition": "" the block gets properly deleted, at least the API is not showing it anymore. 😖

@dsalaza4
Copy link
Author

I created a new token via API by doing:

curl -X POST "https://api.cloudflare.com/client/v4/user/tokens" \
     -H "X-Auth-Email: <email>" \
     -H "X-Auth-Key: <token>" \
     -H "Content-Type: application/json" \
     --data '{"name":"token_manual_2","policies":[{"effect":"allow","resources":{"com.cloudflare.api.account.zone.*":"*"},"permission_groups":[{"id":"82e64a83756745bbbb1c9c2701bf816b","name":"DNS Read"}]}]}'

It looks exactly the same as token_terraform when listing it from the API:

{
  "result":{
    "id":"<token_manual_2_id>",
    "name":"token_manual_2",
    "status":"active",
    "issued_on":"2020-12-18T19:51:50Z",
    "modified_on":"2020-12-18T19:51:50Z",
    "last_used_on":"2020-12-18T19:53:56Z",
    "policies":[
      {
        "id":"38b6b947d56d4ca387d862b501412ea9",
        "effect":"allow",
        "resources":{
          "com.cloudflare.api.account.zone.*":"*"
        },
        "permission_groups":[
          {
            "id":"82e64a83756745bbbb1c9c2701bf816b",
            "name":"DNS Read"
          }
        ]
      }
    ]
  },
...

This one works just fine. Maybe the API token listing endpoint is not showing the cause of the error?

@jacobbednarz
Copy link
Member

FWIW, an empty condition block in the API is not desirable as your IP will be missing from both and will default to a deny ACL rule.

I'm not sure on why the API doesn't return them (maybe to help the user?) but if you don't put the IP!conditions in, it should be omitted completely and not sent.

@dsalaza4
Copy link
Author

@jacobbednarz When I first create the tokens via terraform, even when not specifying a condition block in the code, it still shows up when listing it via API. 🤔

@jacobbednarz
Copy link
Member

Yep, I suspect that is because the fields aren't being correctly checked for zero values and end up appended to the payload. You should be able to confirm this by looking at the TF_LOG=DEBUG output for the HTTP request.

We may also be able to fix this in the cloudflare-go library struct but we'll need to see.

@dsalaza4
Copy link
Author

dsalaza4 commented Dec 18, 2020

@jacobbednarz Just to clarify, doesn't this issue make all CloudFlare API tokens created via Terraform useless? Is there a way for me to fix this until a new version of the provider gets released?

@jacobbednarz
Copy link
Member

No, if you define the conditions, it will work as expected.

@dsalaza4
Copy link
Author

dsalaza4 commented Dec 18, 2020

Sadly, defining conditions is not an option for me, as terraform applies will be executed from:

  1. Distributed continuous integrator where runners have different public ips
  2. Developer local machines with public ips from different countries

I will leave this issue open and wait for a new version of the provider to arrive. Thank you very much for your help!

@accrisoftteam
Copy link

No, if you define the conditions, it will work as expected.

@jacobbednarz I second @dsalaza4 's report that this is not expected functionality. When you create an API Token on Cloudflare's web console or API, no conditions are defined by default. When you create an API token using their terraform provider, a condition of "request_ip is in [] and not in []" is defined by default, which cannot be met. It eliminates Cloudflare's allowed functionality of not defining any conditions. Conditions are an optional parameter. The terraform provider is now forcing them.

https://api.cloudflare.com/#user-api-tokens-create-token

@jacobbednarz
Copy link
Member

I think you've misunderstood the context of that response. Sending empty arrays is not intended or expected (hence also why this is still labelled as a bug). The snippet you've quoted here is in relation to when you actually provide the IP restrictions.

This is in the queue to look at when I'm back from leave which should be on the next couple of weeks unless someone else wants to take a look.

@jacobbednarz jacobbednarz added triage/accepted Indicates an issue or PR is ready to be actively worked on. and removed needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. labels Jan 3, 2021
@jacobbednarz
Copy link
Member

#902 should hopefully address this one

@dsalaza4
Copy link
Author

dsalaza4 commented Jan 6, 2021

I just verified this issue has been fixed. @jacobbednarz Thank you so much for your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Categorizes issue or PR as related to a bug. triage/accepted Indicates an issue or PR is ready to be actively worked on.
Projects
None yet
Development

No branches or pull requests

3 participants