cloudflare / cloudflare/workers-sdk
Worker-minted credentials for existing Artifacts repositories fail, while identical credentials work outside Workers
- Dominant language
- TypeScript
- Stars
- 4.5k
- Forks
- 1.5k
- Avg merge
- 3d 8h
- Merged PRs (30d)
- 186
Description
### Summary
Credentials minted inside a Worker for an existing Cloudflare Artifacts repository cannot authenticate to that repository, while equivalent credentials and requests work from a standalone process.
The documented create/fork flow works when its initial response token is used immediately. The failure is isolated to obtaining credentials later for an existing repository.
### Environment
- Wrangler: `4.125.0`
- Artifacts namespace: a non-production namespace
- Repository: an existing repository created successfully through the Workers binding
- Git client: `isomorphic-git`
### Working flow
Following the documented Worker example literally succeeds:
1. Create a repository.
2. Use the returned `created.remote`.
3. Strip `?expires=` from the returned token for Basic authentication in `onAuth`.
4. Initialize, commit, and push with `isomorphic-git`.
5. Clone the repository with that initial token.
6. Fork the repository.
7. Clone the fork with the token returned by the fork response.
### Failing flow: Workers binding token
For the same ready repository:
```ts
const repo = await env.ARTIFACTS.get("beta-artifacts-auth-rehearsal");
const token = await repo.createToken("read", 300);
```
`createToken` returns a token, but using its suffix-free value as the Basic password for the documented Git `onAuth` flow causes the repository's Git `info/refs` endpoint to return HTTP 403.
### Failing flow: REST token request from Worker
Issuing an existing-repository token through the REST API from the deployed Worker reports `Repository not found` for that same ready repository.
### Controls outside Workers
Against the identical namespace and repository:
- The identical REST credential and request body from a standalone process return HTTP 201.
- Git `info/refs` from a standalone process returns HTTP 200 with the full token as Bearer authentication.
- Git `info/refs` from a standalone process also returns HTTP 200 with the suffix-free token as Basic authentication.
### Expected behavior
A token returned by `repo.createToken("read", 300)` for an existing ready repository should authenticate to that repository's Git endpoint from a Worker, using the documented Basic authentication flow.
Alternatively, issuing an existing-repository token through the REST API from a Worker should resolve the same repository in the same way as the identical request from a standalone process.
### Actual behavior
| Credential path | Runtime | Result |
| --- | --- | --- |
| Initial token returned by repository creation | Worker | Git push and clone succeed |
| Token returned by fork | Worker | Git clone succeeds |
| `repo.createToken("read", 300)` on existing repository | Worker | Token returned; Git `info/refs` returns 403 |
| REST existing-repository token issuance | Worker | `Repository not found` |
| Identical REST request | Standalone process | 201 |
| Equivalent token, suffix-free Basic | Standalone process | Git `info/refs` returns 200 |
| Equivalent token, full-token Bearer | Standalone process | Git `info/refs` returns 200 |
### Documentation followed
- https://developers.cloudflare.com/artifacts/api/workers-binding/
- https://developers.cloudflare.com/artifacts/api/rest-api/
- https://developers.cloudflare.com/artifacts/api/git-protocol/
- https://developers.cloudflare.com/artifacts/examples/isomorphic-git/
No repository tokens, API tokens, account identifiers, or other credentials are included here. I can provide request IDs or a smaller reproduction if useful.
Contributor guide
Research direction
Start with the Workers binding `repo.createToken("read", 300)` path and the REST existing-repository token request, then compare their repository resolution and authentication behavior with the standalone controls. Done means a token for an existing repository works against Git `info/refs` from a Worker and the equivalent REST request no longer reports `Repository not found`.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- git, typescript
- Domain
- authentication, backend-api-design, cloud
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100