go-gitea / gitea

Git with a cup of tea! Painless self-hosted all-in-one software development service, including Git hosting, code review, team collaboration, package registry and CI/CD
https://gitea.com
MIT License
44.08k stars 5.41k forks source link

actions: login via GITEA_TOKEN to package repository not working #23642

Open krombel opened 1 year ago

krombel commented 1 year ago

Description

I am having this snippet in a workflow file:

      - name: Log in to the Container registry
        uses: docker/login-action@v2
        with:
          registry: my.gitea.domain
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITEA_TOKEN }}

I exchanged github.repository_owner with github.actor as well. Bot did not work.

I see the following error in the actions run log:

Log in to the Container registry
Logging into my.gitea.domain...
::error::Error response from daemon: login attempt to https://my.gitea.domain/v2/ failed with status: 401 Unauthorized

Gitea Version

1.19.0

Can you reproduce the bug on the Gitea demo site?

No

Log Gist

No response

Screenshots

No response

Git Version

No response

Operating System

No response

How are you running Gitea?

I am running it in a docker container and am reverse proxying the https port.

Database

None

dboreham commented 1 year ago

Token scope was added in 1.19 so perhaps your token needs to be re-issued with a new scope (this happened to me in a slightly different context but where I could see the full error response from gitea which mentioned the token scope being inadequate).

lunny commented 1 year ago

Did you set your ROOT_RUL in app.ini to my.gitea.domain ?

krombel commented 1 year ago

Token scope was added in 1.19 so perhaps your token needs to be re-issued with a new scope (this happened to me in a slightly different context but where I could see the full error response from gitea which mentioned the token scope being inadequate).

@dboreham How do you do that? As far as I understood that specific token is a task defined token which would not affect any secrets I have defined myself. https://github.com/go-gitea/gitea/blob/be93e48ccb73acfaa372e56217105d3420e1a40e/routers/api/actions/runner/utils.go#L70

Did you set your ROOT_RUL in app.ini to my.gitea.domain ?

I think there is a typo 😉 . I set ROOT_URL at least to https://my.gitea.domain

KN4CK3R commented 1 year ago

Does it work from the command line? docker login -u ... -p token my.gitea.domain

krombel commented 1 year ago

The package repository itself is working. When I try to use a pregenerated secret and use that, it is working as well. What is not working ist the use of the GITEA_TOKEN to publish data into the package repository.

yp05327 commented 1 year ago

401 Unauthorized is returned by ReqContainerAccess (defined in routers/api/packages/container/container.go)

I removed container.ReqContainerAccess here, it returns success.(not a fix, just a test) https://github.com/go-gitea/gitea/blob/d02e83a2c3e0bd1bc1150c4ed976928d967ac3f5/routers/api/packages/api.go#L460 image

KN4CK3R commented 1 year ago

Just a note: That looks like it works but you can't upload a container or other things.

philkunz commented 1 year ago

What is the status on this one?

lunny commented 1 year ago

It depends on the trigger user's permission to that package. And you can always use a PAT to do that.

philkunz commented 1 year ago

Ok, but 1.19.3 still does not pay respect to that, or? Because the build happens on push through me, I'm the owner of the repo and it still fails with authentication required after using GITEA_TOKEN for a successful Docker Login.

Which is the earliest version that works?

KN4CK3R commented 1 year ago

The linked PR is active with 1.20

AndyTempel commented 1 year ago

Currently on 1.20.0-rc2 and this works:

- name: Log in to the Container registry
  uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
  with:
      registry: git.example.com
      username: ${{ gitea.repository_owner }}
      password: ${{ secrets.GITEA_TOKEN}}

But push fails with: docker/build-push-action@2eb1c1961a95fc15694676618e422e8ba1d63825

#28 [auth] *:: project/app:pull,push token for git.example.com
#28 DONE 0.0s
#29 [auth] sharing credentials for git.example.com
#29 DONE 0.0s
#27 exporting to image
#27 pushing layers 1.0s done
#27 ERROR: failed to push git.example.com/project/app:master: unexpected status: 401 Unauthorized
------
 > exporting to image:
------
ERROR: failed to solve: failed to push git.example.com/project/app:master:master: unexpected status: 401 Unauthorized
::error::buildx failed with: ERROR: failed to solve: failed to push git.example.com/project/app:master:master: unexpected status: 401 Unauthorized
krombel commented 1 year ago

That is right as @KN4CK3R mentioned before: https://github.com/go-gitea/gitea/issues/23642#issuecomment-1482584036

Here it got decided to temporarily only allow read only access and postpone the permission check: https://github.com/go-gitea/gitea/pull/23729#issuecomment-1492774010

The underlining issue is an ongoing discussion how to manage permissions in general. There is a proposal in https://github.com/go-gitea/gitea/issues/24635 but nothing implemented in that direction yet (AFAIK)

sgabenov commented 12 months ago

You can try to specify token within url

      - name: Delete git repository old branches
        uses: https://${{ secrets.GIT_ACCESS_TOKEN }}:@gitea.my.domain/emb_tools/gitea-actions-delete-abandoned-branches@v1
        id: delete_stuff
PatrickHuetter commented 11 months ago

Currently on 1.20.0-rc2 and this works:

- name: Log in to the Container registry
  uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
  with:
      registry: git.example.com
      username: ${{ gitea.repository_owner }}
      password: ${{ secrets.GITEA_TOKEN}}

But push fails with: docker/build-push-action@2eb1c1961a95fc15694676618e422e8ba1d63825

#28 [auth] *:: project/app:pull,push token for git.example.com
#28 DONE 0.0s
#29 [auth] sharing credentials for git.example.com
#29 DONE 0.0s
#27 exporting to image
#27 pushing layers 1.0s done
#27 ERROR: failed to push git.example.com/project/app:master: unexpected status: 401 Unauthorized
------
 > exporting to image:
------
ERROR: failed to solve: failed to push git.example.com/project/app:master:master: unexpected status: 401 Unauthorized
::error::buildx failed with: ERROR: failed to solve: failed to push git.example.com/project/app:master:master: unexpected status: 401 Unauthorized

Same result for me with gitea 1.20.4. How do you push the docker images to the gitea container registry from within the gitea actions? Do you use custom PATs instead the GITEA_TOKEN/GITHUB_TOKEN?

krombel commented 11 months ago

@PatrickHuetter You must use PATs for writing to package repositories right now. As mentioned in my comment before there is no implementation yet - not in master and therefore in no release either - to use GIT{EA,HUB}_TOKEN for pushing to package repositories.

PatrickHuetter commented 11 months ago

@PatrickHuetter You must use PATs for writing to package repositories right now. As mentioned in my comment before there is no implementation yet - not in master and therefore in no release either - to use GIT{EA,HUB}_TOKEN for pushing to package repositories.

Thanks @krombel. I got it working with PATs.

the-maldridge commented 6 months ago

This should be listed as a missing feature on this page. My organization does not permit static PATs to be used in workflows, which means we can't use that as a workaround. It would have been much easier to figure out this is why the permissions error occurs if it had been listed in the documentation as a current limitation.

Elbandi commented 5 months ago

it doesnt work for me with user PAT:

docker login git.domain.hu -u jenkins -p 3132131231231232
docker push git.domain.hu/elbandi/test

i added some debug logs:

2024/04/06 20:56:30 ...es/container/auth.go:31:Verify() [I] uid: 7
2024/04/06 20:56:30 ...es/container/auth.go:37:Verify() [I] GetPossibleUserByID() u:<User 7:jenkins>
2024/04/06 20:56:30 ...es/container/auth.go:37:Verify() [I] GetPossibleUserByID() u:<User 7:jenkins>
2024/04/06 20:56:30 .../api/packages/api.go:44:func5() [I] reqPackageAccess: Data["IsApiToken"]: <nil>, Data["ApiTokenScope"]: <nil>
2024/04/06 20:56:30 .../api/packages/api.go:44:func4() [I] reqPackageAccess: Data["IsApiToken"]: <nil>, Data["ApiTokenScope"]: <nil>
2024/04/06 20:56:30 .../api/packages/api.go:44:func5() [I] reqPackageAccess: Data["IsApiToken"]: <nil>, Data["ApiTokenScope"]: <nil>
2024/04/06 20:56:30 .../api/packages/api.go:44:func4() [I] reqPackageAccess: Data["IsApiToken"]: <nil>, Data["ApiTokenScope"]: <nil>
2024/04/06 20:56:30 ...eb/routing/logger.go:102:func1() [I] router: completed POST /v2/elbandi/test/blobs/uploads/ for 192.168.200.40:0, 401 Unauthorized in 1.2ms @ packages/api.go:43(packages.ContainerRoutes.func2.1.reqPackageAccess)

So looks like container.Verify() found the right user, but doesnt fill the IsApiToken and ApiTokenScope data fields. therefore reqPackageAccess denied the access.

Gitea version: 1.21.10 built with GNU Make 4.2.1, go1.21.9 : bindata, sqlite, sqlite_unlock_notify

lunny commented 5 months ago

docker login

I cannot reproduce this. Please check your PAT's permission which has read/write packages permission.

Elbandi commented 5 months ago

docker login

I cannot reproduce this. Please check your PAT's permission which has read/write packages permission.

scope: all, and "jenkins" user is added to project with write permission. (ofc just for testing)

lunny commented 5 months ago

You still need to choose the permissions after choosing ALL in the UI. ALL means all of the repositories which don't mean permissions.

image
Elbandi commented 5 months ago

You still need to choose the permissions after choosing ALL in the UI. ALL means all of the repositories which don't mean permissions.

As i said, all permissions are added. i listed the tokes by api:

 GET /api/v1/users/jenkins/tokens

Response:

 [
  {
    "id": 8,
    "name": "runner",
    "sha1": "",
    "token_last_eight": "bf14d900",
    "scopes": [
      "all"
    ]
  }
]
yp05327 commented 5 months ago

If the owner of this repo is organization, does this user have the permission to access organization packages?

KN4CK3R commented 4 months ago

I don't think this is implemented. The job token can't be used to publish packages at the moment.

Elbandi commented 3 months ago

It look like, token is not working for personal repo (eg: elbandi/test) Here, i create a new token for jenkins user with full access:

$ sudo -u git /usr/local/sbin/gitea admin user generate-access-token --username jenkins --token-name testtoken --scopes "all"
Access token was successfully created: 2bcb4b4293d6f624b49d22cd8f8f46b800c65cc5

I verify, that jenkins user has write permission to elbandi/test:

curl -X 'GET' \
  'https://git.domain.hu/api/v1/repos/elbandi/test/collaborators/jenkins/permission' \
  -H 'accept: application/json' \
  -H 'authorization: Basic xxxx'

result (look good: jenkins has write role to elbandi/test):

{
  "permission": "write",
  "role_name": "write",
  "user": {
    "id": 7,
    "login": "jenkins",
    "login_name": "",
    "full_name": "Jenkins build system",
    "email": "jenkins@domain.hu",
    "language": "",
    "is_admin": false,
    "last_login": "1970-01-01T01:00:00+01:00",
    "created": "2021-03-03T00:07:56+01:00",
    "restricted": false,
    "active": true,
    "prohibit_login": false,
    "location": "",
    "website": "",
    "description": "",
    "visibility": "public",
    "followers_count": 0,
    "following_count": 0,
    "starred_repos_count": 0,
    "username": "jenkins"
  }
}

Try to upload a file as a generic package to elbandi/test:

$ curl --user jenkins:2bcb4b4293d6f624b49d22cdbf8f46b800c65cc5 \
 --upload-file README.md \
 https://git.elbandi.net/api/packages/elbandi/generic/test/1.0.0/file.bin
reqPackageAccess
$

unsuccessful :(

Try to upload a file as a generic package to an organisation package:

$ curl --user jenkins:2bcb4b4293d6f624b49d22cdbf8f46b800c65cc5 \
  --upload-file README.md \
  https://git.elbandi.net/api/packages/kubernetes/generic/test/1.0.0/file.bin
$

it works.

chrisliebaer commented 3 months ago

Sadly, this issue covers quite an important feature, but the discussion has been dissolved by unrelated topics of improper configuration.

As highlighted by others, at the very least, a note should be placed here: https://docs.gitea.com/usage/actions/comparison#missing-features I just spent 2 hours assuming that Gitea would support this feature, as it's very common and not listed.

Creating a PAT does not solve this issue. A PAT can not be scoped to a single repo, has to be created manually, and managed / copied / or stored (unless we want to end up with multiple PATs)

Gitea already associates packages with repos, so mirroring GitHubs should probably be supported without changes to Giteas design.

The basic flow should probably be something like this:

  1. runner token gets access to write (some) packages of ${{ github.repository_owner }} namespace
  2. packages uploaded with this token get added to ${{ github.repository_owner }} packages and associated with repo
  3. if the package is already associated with a different repo (one for which we don't have an access token) the modification is rejected

This also means that if UserB pushes changes to a repo owned by UserA, the token will have access to the UserA package namespace.

Now I don't have any idea what your goals and concerns are, but PATs should be seen as a workaround, not as a solution, since they are clumsy, error-prone and give access to the namespace of the owner.

philkunz commented 3 months ago

@lunny What would be the right way of getting this going?

lunny commented 3 months ago

Create a PAT with permission of package and use that PAT to do login, push.

alex3305 commented 1 month ago

As a temporary workaround I have defined an actions user which I gave sufficient rights on the repositories that I want to use actions with. Or in my case I've made this an admin user which cannot login through the web UI. The latter I disabled as a final step.

For this user I created a PAT ~and set that up as a secret variable on the Actions > Secrets page on the user's profile as PACKAGES_TOKEN so I can use that variable within my Actions.~ Appearently I still have to set that PAT on my own profile as well. Otherwise the secret cannot be found. I can than use a pretty similar approach to the intended one:

name: Docker Build and Push
run-name: ${{ gitea.actor }} is running Docker build and push

on:
  push:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      - name: Login to local Gitea registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.registry }}
          username: ${{ env.actions_user }}
          password: ${{ secrets.PACKAGES_TOKEN }}
      - name: Docker Build and push
        uses: docker/build-push-action@v6
        with:
          context: .
          push: true
          tags: ${{ env.registry }}/${{ gitea.repository }}:latest

Note that I also defined my registry and actions user in my runner's config.yaml:

runner:
  envs:
    registry: gitea.mydomain.tld
    actions_user: actions

This seems to work perfectly. Or at least for the time being 😄 .

Instead of using a dedicated user you could also opt to set your own username as the actions_user and add the PAT to your Actions > Secrets in your profile.