Commit 9291203
Re-authenticate against OCI registry after 403 error
Writing to an OCI registry, as done with `devcontainer features publish`
requires authentication against the registry with the `push` OAuth
scope. Currently, devcontainer CLI only authenticates or
re-authenticates if the registry returns a 401 error (invalid_token).
But some registries, notably the IBM Container Registry (icr.io) may
also return a 403 error (insufficient_scope) in case of a request being
authenticated, but without sufficient scopes (i.e., the token was only
valid for the `pull` scope, but `push,pull` was required for write
access).
Update the code to attempt to re-authenticate in case of a 403 error,
just like it's done for a 401 error. The server does supply the correct
scope in its `WWW-Authenticate` header and subsequent requests will then
work as expected.
See also [RFC 6750, Section 3.1 (Error Codes)](https://datatracker.ietf.org/doc/html/rfc6750#section-3.1)
for a standards reference.
This improvement makes `devcontainer features publish` work with IBM
Cloud Container Registry.
---
Test:
```
$ devcontainer.js features publish --registry icr.io -n my-ns/features ~/my-feature`
```
HTTP trace (abbreviated) *before* this change:
```
-> POST https://icr.io/v2/my-ns/features/my-feature/tags/list
-> 401 Unauthorized
www-authenticate: Bearer realm="https://icr.io/oauth/token",service="registry",scope="repository:my-ns/features/my-feature:pull"
-> POST https://icr.io/oauth/token
client_id=devcontainer&grant_type=refresh_token&service=registry&scope=repository%3Amy-ns%2Ffeatures%2Fmy-feature%3Apull&refresh_token=...
<- 200 OK
-> POST https://icr.io/v2/my-ns/features/my-feature/blobs/uploads/
authorization: Bearer
<- 403 Forbidden:
www-authenticate: Bearer realm="https://icr.io/oauth/token",service="registry",scope="repository:my-ns/features/my-feature:pull,push",error="insufficient_scope"
```
HTTP trace (abbreviated) before *after* change:
```
-> POST https://icr.io/v2/my-ns/features/my-feature/tags/list
-> 401 Unauthorized
www-authenticate: Bearer realm="https://icr.io/oauth/token",service="registry",scope="repository:my-ns/features/my-feature:pull"
-> POST https://icr.io/oauth/token
client_id=devcontainer&grant_type=refresh_token&service=registry&scope=repository%3Amy-ns%2Ffeatures%2Fmy-feature%3Apull&refresh_token=...
<- 200 OK
-> POST https://icr.io/v2/my-ns/features/my-feature/blobs/uploads/
authorization: Bearer
<- 403 Forbidden:
www-authenticate: Bearer realm="https://icr.io/oauth/token",service="registry",scope="repository:my-ns/features/my-feature:pull,push",error="insufficient_scope"
-> POST https://icr.io/oauth/token
client_id=devcontainer&grant_type=refresh_token&service=registry&scope=repository%3Amy-ns%2Ffeatures%2Fmy-feature%3Apull%2Cpush&refresh_token=...
<- 200 OK
```
Note the second auth request after the 403 response.1 parent e0598db commit 9291203
1 file changed
+5
-5
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
37 | 37 | | |
38 | 38 | | |
39 | 39 | | |
40 | | - | |
| 40 | + | |
41 | 41 | | |
42 | 42 | | |
43 | 43 | | |
| |||
54 | 54 | | |
55 | 55 | | |
56 | 56 | | |
57 | | - | |
58 | | - | |
59 | | - | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
60 | 60 | | |
61 | 61 | | |
62 | 62 | | |
63 | 63 | | |
64 | | - | |
| 64 | + | |
65 | 65 | | |
66 | 66 | | |
67 | 67 | | |
| |||
0 commit comments