integrations / terraform-provider-github

Terraform GitHub provider
https://www.terraform.io/docs/providers/github/
MIT License
912 stars 754 forks source link

Data source github_actions_public_key returns a 404 #667

Open amogram opened 3 years ago

amogram commented 3 years ago

Terraform Version

Terraform 0.13.6

Affected Resource(s)

Terraform Configuration Files

provider "github" {
  token        = var.github_token
  organization = "buffalogrid"
}

data "github_actions_public_key" "repo_public_key" {
  repository = var.repo
}

resource "github_actions_secret" "secret" {
  for_each = var.config

  repository      = var.repo
  secret_name     = upper(join("_", [var.env, each.key]))
  plaintext_value = each.value
}

Provider configuration:

terraform {
  required_providers {
    github = {
      source  = "integrations/github"
      version = "~> 4.3.0"
    }
  }
}

Debug Output

https://gist.github.com/amogram/a937c1f0d83ec8dee2a390ed8fdcecf6

Panic Output

Expected Behavior

The data source should retrieve information about a GitHub Actions public key.

Actual Behavior

The call returns a 404. The makeup of the GET request doesn't appear to be correct. It seems to be missing the organization name.

It appears to be a similar issue to #655 and what is discussed here: https://github.com/integrations/terraform-provider-github/issues/652#issuecomment-763603673

Error: GET https://api.github.com/repos//bg-dashboards-and-control-panels-frontend/actions/secrets/public-key: 404 Not Found []

  on github-repo-secrets/main.tf line 1, in data "github_actions_public_key" "repo_public_key":
   1: data "github_actions_public_key" "repo_public_key" {

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. Added the data source.
  2. Organisation is set in the provider.
  3. Run terraform plan.

Important Factoids

References

It appears to be a similar issue to #655 and what is discussed here: https://github.com/integrations/terraform-provider-github/issues/652#issuecomment-763603673

estahn commented 3 years ago

We have a same/similar issue:

Error: GET https://api.github.com/repos//foobar/actions/secrets/public-key: 404 Not Found []

  on service-foobar.tf line 133, in resource "github_actions_secret" "github-actions-foobar-access-key":
 133: resource "github_actions_secret" "github-actions-foobar-access-key" {
tmegow commented 3 years ago

github_actions_public_key data source is failing because my github organization requires SAML auth:

404/Not Found when sending requests without SSO Auth Token as header:

curl -i https://api.github.com/repos/myrepo/actions/secrets/public-key
{
  "message": "Not Found",
  "documentation_url": "https://docs.github.com/rest"
}

Successful response when providing an SSO-enabled Github Personal Access Token (PAT) as an Authorization header.

curl -i -H "Authorization: token myuser-github-token" https://api.github.com/repos/myrepo/actions/secrets/public-key
{
  "key_id": "<>",
  "key": "<>"
}

There is no way I can see using to authenticate to Github organizations requiring SAML auth in the github_actions_public_key data source.

--

Alternate question, I possess the public key value which the github_actions_public_key data source wishes to retrieve. Am I able to set this variable in TF so the github_actions_secret resource can use it? I've tried plugging it into local variables named github_actions_public_key and that does not work.

oliverbenns commented 2 years ago

Migrating to integrations/github from hashicorp/github and using latest does not seem to resolve this issue. Did anyone have any recent success?

alicyn commented 2 years ago

I was able to solve this by setting these ENV variables. export GITHUB_TOKEN=<Personal Access Token with write permissions> export GITHUB_OWNER=<owner_name>

maheshbhole commented 2 years ago

tried everything in this thread, nothing work. Does anybody know about cause of this ?

actions/secrets/public-key: 404 Not Found []

Tedezed commented 2 years ago

Debug with curl first: https://docs.github.com/en/rest/actions/secrets#get-a-repository-public-key

Verifications:

  1. Make sure the repository name and owner are correct (you may have a typo).
  2. If your repository is private, verify that with the token you can see it, it is possible that you do not have permissions.
  3. Verify that the GITHUB_OWNER and GITHUB_TOKEN variables are correct.

With these steps you should be able to solve it 🥳

ahilmathew commented 2 years ago

Your PAT token needs to have the read:public_key permissions under admin:public_key.

tiagojsag commented 2 years ago

hey all; after combing through the different replies here, and trying a bunch of different things, I simplest way I could get this to work is to leave the provider config empty, and just pass these two env vars when calling the terraform CLI:

GITHUB_OWNER=<gh org name> GITHUB_TOKEN=<gh access token> terraform apply

There are, ofc, different ways to achieve this, but I just wanted to leave this as a one-line copy/paste-able workaround to this problem. hope it helps others until the underlying issue is fixed.

paullatzelsperger commented 2 years ago

just found out that there may be a typo in the terraform provider. Terraform reports an error: GET https://api.github.com/repos//<ORG>/<REPO>/actions/secrets/public-key note the double forward slashes. They get added, regardless whether I prefix the repository string or not.

immanetize commented 2 years ago

I can confirm @paullatzelsperger's observation:

$ curl   -H "Accept: application/vnd.github+json"   -H "Authorization: Bearer $TOKEN"   https://api.github.com/repos/$ORG/$REPO/actions/secrets/public-key 
{
  "key_id": "REDACTED",
  "key": "ESPECIALLY_REDACTED"
}
$ curl   -H "Accept: application/vnd.github+json"   -H "Authorization: Bearer $TOKEN"   https://api.github.com/repos//$ORG/$REPO/actions/secrets/public-key
{
  "message": "Not Found",
  "documentation_url": "https://docs.github.com/rest"
}
immanetize commented 2 years ago

from what I can tell, https://github.com/integrations/terraform-provider-github/blob/main/vendor/github.com/google/go-github/v48/github/actions_secrets.go#L51 concatenates the provided URL with the base URL and adds a separating /, but https://github.com/integrations/terraform-provider-github/blob/main/github/config.go#L87 the base URL ends with a /. I imagine that means all .client invocations' url need to be prepended with a forward slash; I'm not sure if confident enough with Go to take this on though.

immanetize commented 2 years ago

... no, sorry, if the / is implicitly injected one doesn't prepend the API urls with it. Time for more coffee...

henrybirch commented 1 year ago

Hi, is there a work around for this as I am getting the double slash in my get request url when using the github_actions_secret resource and I've not found a way to fix it.

I can swear that I had this working yesterday but I changed my terraform module structure and now there's a double slash there :(

iskarconsulting commented 1 year ago

I got this working with the following configuration:

Configure a fine-grained PAT with secrets.write permission.

GitHub Actions Workflow:

...

jobs:
  terraform:
    name: 'Terraform'
    runs-on: ubuntu-latest

    env:
      TF_VAR_github_repository: ${{ github.repository }}
      TF_VAR_github_token: ${{ secrets.GH_REPOSITORY_SECRETS_PAT }}

...

main.tf

...

provider "github" {
  owner = split("/", var.github_repository)[0]
  token = var.github_token
}

...

secret.tf

...

resource "github_actions_secret" "secret" {
  repository      = split("/", var.github_repository)[1]
  secret_name     = "SECRET_NAME"
  plaintext_value = <secret>
}

...

Note: I tried to get this working with the built in GitHub Actions GITHUB_TOKEN but was getting the response:

403 Resource not accessible by integration []

Unfortunately, there doesn't seem to be a way to assign secrets.write to the GITHUB_TOKEN. Ideally, I'd like to avoid using a PAT as it's another secret to manage (it'll expire and will need rotating).

enchorb commented 1 year ago

Any ETA on a provider fix here?

kfcampbell commented 1 year ago

@enchorb the issue being discussed here is almost always indicative of an authentication issue: either auth is not passed to the Terraform module correctly (using env vars with a PAT tends to be the approach most find success with) or else the token does not have proper permissions.

Ideally, we'd have a better error message for this when we can see we have no auth or user configured in such operations (contributions are appreciated!).

aderesh commented 1 year ago

@kfcampbell

The following curl request works for me (fine-grained token with Secrets and Variable 'Read and Write' access in test repo): Request:

curl \
  -H "Accept: application/vnd.github+json" \
  -H "Authorization: Bearer github_pat_1*****"\
  -H "X-GitHub-Api-Version: 2022-11-28" \
  https://api.github.com/repos/aderesh/test/actions/secrets/public-key

Response (redacted):

{
  "key_id": "568****",
  "key": "rBrz****"
}

This is the error message I receive when using TF provider:

│ Error: GET https://api.github.com/repositories/340989967/test/actions/secrets/public-key: 404 Not Found []
│
│   with github_actions_secret.TF_TEST,
│   on github.tf line 5, in resource "github_actions_secret" "TF_TEST":
│    5: resource "github_actions_secret" "TF_TEST" {
│

So, I tried to use this URL with the same token and it didn't work: Request (redacted):

curl \
  -H "Accept: application/vnd.github+json" \
  -H "Authorization: Bearer github_pat_1***"\
  -H "X-GitHub-Api-Version: 2022-11-28" \
  https://api.github.com/repositories/340989967/test/actions/secrets/public-key

Response:

{
  "message": "Not Found",
  "documentation_url": "https://docs.github.com/rest"
}

Therefore, it's not a token issue since the token is the same in both cases

Note the differences between URLs:

  1. TF providers use https://api.github.com/repositories/ while the one that works for me is https://api.github.com/repos/ (https://docs.github.com/en/rest/actions/secrets?apiVersion=2022-11-28#get-a-repository-public-key). Those are different endpoints.
  2. TF provider uses my integer ID (340989967) while I used my string id for the request that works (aderesh).

I've tried different combinations with https://api.github.com/repositories/ and https://api.github.com/repos/: used string id and int id in both. However, only https://api.github.com/repos/aderesh/test/actions/secrets/public-key works for me. Also, I've tried to provide owner (e.g. aderesh) in 'github' provider configuration, but the error message is exactly the same.

TF config:

    github = {
      source  = "integrations/github"
      version = "5.18.0"
    }

    ...

    provider "github" {
  token = var.github_token # or `GITHUB_TOKEN`
  #owner = var.github_owner - I've tried w/ and w/o - no difference
}

Vars

github_token = "github_pat_1*"
github_repo  = "aderesh/test"
github_owner = "aderesh"

It does look like an error in the provider, tbh.

aderesh commented 1 year ago

Based on the @iskarconsulting config (huge thanks!), I believe the following causes the 404 error: Secret's repository field should be just repo name without the owner part. For instance, it should be "test" instead of "aderesh/test". it works even without providing "owner" in the provider configuration for me.

Full solution:

github_token = "github_pat_1*****"
github_repo  = "aderesh/test"
provider "github" {
  token = var.github_token 
}
variable "github_repo" {
  type = string
}

resource "github_actions_secret" "TF_TEST" {
  repository      = split("/", var.github_repo)[1]
  secret_name     = "TF_TEST"
  plaintext_value = "secret"
}

PAT: Fine-grained with Secrets:Read and Write, scoped to test repo.

It would be nice to know if there are terms/names for "REPO" and "OWNER/REPO" (e.g. repository vs full_repository_name)? It's been always confusing to me when to use which...

maulik13 commented 1 year ago

The Github provider has a very peculiar behavior when it comes to how the URL is built and it is not documented. Basically there are two cases you are dealing with,

  1. Using PAT: Owner is automatically determined from the token and added to the URL. So if your repository variable in resource is owner/repo you have to remove the owner in order to avoid repeating the owner. We confirmed this for github_actions_environment_secret and most likely it is the same for other resources.
  2. Using GitHub App: In this case, you have to use the full repository name in the variable e.g. owner/repo. In our test, the owner parameter in the provider did not affect the output. However, in this case we face an issue when dealing with github_actions_environment_secret because of the extra backslash character added in the URL. The solution to fix this was making sure you are using the right provider in the root module (integration\github and not hashicorp\github) and pass the owner in the root module.

Summary: Remove the owner from the repository parameter value When using PAT, owner is automatically fetched based on the token For GitHub App you need to pass the owner in the root

kfcampbell commented 1 year ago

@maulik13 That is excellent information. Would you be receptive to creating a PR for our docs to describe this behavior? Ideally, we'd make this more consistent across the provider, but that would likely be a breaking change to work up towards with a deprecation notice.

tfc-github commented 1 year ago

I'm using PAT that generated from org owner account, I'm trying to use TF to push and manage orgnization secret for one private repo github actions, below is how I get it working. I noticed there is a Warning message from terraform when I used organization in my provider block. The message said:

Warning: "organization": [DEPRECATED] Use owner (or GITHUB_OWNER) instead of organization (or GITHUB_ORGANIZATION) │ │ with provider["registry.terraform.io/integrations/github"], │ on providers.tf line 237, in provider "github": │ 237: provider "github" {

So I followed the warning, instead of using organization I used GITHUB_ORGANIZATION. so my provider block looks like this: provider "github" { GITHUB_ORGANIZATION = var.github_org token = (sensitive(aws_ssm_parameter.githubtfctoken.value)) } my resource block looks like this: data "github_repository" "my_private_repo" { full_name = "/" }

resource "github_actions_organization_secret" "org_secret_test" { secret_name = "terraform_test" visibility = "selected" encrypted_value = "terraformtestsecretvalue" selected_repository_ids = [data.github_repository.my_private_repo.repo_id] }

I checked from github actions on that repo and found this secret created there: image

jackton1 commented 1 year ago

To resolve this I had to update the GITHUB_TOKEN with the correct scope Screenshot 2023-07-14 at 5 04 36 PM

Warren-Byron commented 1 year ago

To resolve this I had to update the GITHUB_TOKEN with the correct scope Screenshot 2023-07-14 at 5 04 36 PM

I looked at @jackton1's solution and realised that my permission settings were different. I had been using a Fine-grained-token (beta) PAT.

So I generated a Token (classic) PAT and set the permission as per Jackson's solution and this worked 🎉 !

This could mean the module doesn't work with the fine-grained "beta" tokens... OR Perhaps my permissions weren't correct under the fine-grained tokens, however I did follow the recommended settings from a Github tutorial / documentation when I set those permissions initially.

Warren-Byron commented 1 year ago

I did an experiment and tried to give a Fine-grained token full / super admin permissions (i.e. with full rights to everything).

I ended up back where I was i.e. the error being experienced in this forum reoccured, that tells me you need to use the Classic Token (with the correct permissions) and it doesn't work with the Fine Grained Token (for some reason 🤷 ).

fr-esco commented 7 months ago

To resolve this I had to update the GITHUB_TOKEN with the correct scope Screenshot 2023-07-14 at 5 04 36 PM

Thanks a lot. It's still an issue today, with version 6.2.1.

I tried a lot of fine-grained token permission combinations without success. Switching to a "classic" personal access token made the integration work.

chrisrosner commented 1 month ago

I think I ran in to a bug here too? It seems this provider always inserts your username if you're using classic PAT unless you set the GITHUB_OWNER variable.

For me, I'm trying to create secrets in an organization repo, which my token has permissions to do.

It works if I set GITHUB_OWNER=(organization)

It does not work if that variable is not set, instead, it forms this wrong url: GET https://api.github.com/repos/(username)/(repo)/actions/secrets/public-key

It should have been: GET https://api.github.com/repos/(organization)/(repo)/actions/secrets/public-key