Expected behavior and actual behavior
I expect to be able to access all API endpoints that my user has access to via e.g. curl, using my CLI secret for authentication.
However, when using an OIDC user account, I cannot access some endpoints:
- I can
GET the list of projects, but I cannot GET a specific project.
- I can
GET the list of repositories in a project, but I cannot GET a specific repository.
- I can
GET the list of artifacts in a repository, but I cannot GET a specific artifact (or e.g. its vulnerabilities).
Specifically, when using curl, I get a 401 response with this body:
{"errors":[{"code":"UNAUTHORIZED","message":"unauthorized"}]}
I can access all endpoints with curl using a robot account or the admin account (which do not use OIDC).
I can also access all endpoints in the web GUI and the API Explorer (/devcenter-api-2.0) using my OIDC account.
Steps to reproduce the problem
HARBOR_USERNAME="bob"
HARBOR_PASSWORD="…"
HARBOR_URL="https://example.com"
HARBOR_PROJECT="foo"
HARBOR_REPO="bar"
HARBOR_TAG="baz"
API_PATHS=(
"/projects"
"/projects/${HARBOR_PROJECT:?}"
"/projects/${HARBOR_PROJECT:?}/repositories"
"/projects/${HARBOR_PROJECT:?}/repositories/${HARBOR_REPO:?}"
"/projects/${HARBOR_PROJECT:?}/repositories/${HARBOR_REPO:?}/artifacts"
"/projects/${HARBOR_PROJECT:?}/repositories/${HARBOR_REPO:?}/artifacts/${HARBOR_TAG:?}"
"/projects/${HARBOR_PROJECT:?}/repositories/${HARBOR_REPO:?}/artifacts/${HARBOR_TAG:?}/additions/vulnerabilities"
)
for apiPath in "${API_PATHS[@]}"; do
curl --silent --output /dev/null --write-out "%{http_code} %{url_effective}\n" -u ${HARBOR_USERNAME:?}:${HARBOR_PASSWORD:?} "${HARBOR_URL:?}/api/v2.0${apiPath}"
done
Output:
200 https://example.com/api/v2.0/projects
401 https://example.com/api/v2.0/projects/foo
200 https://example.com/api/v2.0/projects/foo/repositories
401 https://example.com/api/v2.0/projects/foo/repositories/bar
200 https://example.com/api/v2.0/projects/foo/repositories/bar/artifacts
401 https://example.com/api/v2.0/projects/foo/repositories/bar/artifacts/baz
401 https://example.com/api/v2.0/projects/foo/repositories/bar/artifacts/baz/additions/vulnerabilities
Lines like this one show up in the log:
2022-04-04T14:00:00Z [ERROR] [/server/middleware/security/basic_auth.go:40][requestID="…"]: failed to authenticate bob: not supported
The error is thrown here.
Additional information
Notably, it turns out that in the web GUI and the API Explorer, a cookie named sid is included in each request. That cookie alone turns out to be enough for authentication and authorization – the Authorization header (i.e. curl's -u flag) is not even needed:
HARBOR_SID="deadbeefdeadbeefdeadbeefdeadbeef"
curl --silent --output /dev/null --write-out "%{http_code} %{url_effective}\n" --cookie "sid=${HARBOR_SID:?}" "${HARBOR_URL:?}/api/v2.0/projects/${HARBOR_PROJECT:?}"
As previously stated, the cookie is necessary for some endpoints (when accessed by an OIDC user). However, the API Explorer generates commands like this one, without any cookie:
curl -X 'GET' \
'https://example.com/api/v2.0/projects/foo' \
-H 'accept: application/json' \
-H 'X-Is-Resource-Name: false' \
-H 'authorization: Basic Ym9iOm15IENMSSBzZWNyZXQK'
All in all, there seems to be some inconsistency regarding OIDC authentication:
- When the API is accessed by an OIDC user, some endpoints (e.g.
/projects/foo) require an OIDC cookie, while others (e.g. /projects) do not.
- In the API Explorer, commands without necessary authentication information are displayed.
Versions
- Harbor version: 2.4.1
- docker engine version: N/A
- docker-compose version: N/A
Expected behavior and actual behavior
I expect to be able to access all API endpoints that my user has access to via e.g. curl, using my CLI secret for authentication.
However, when using an OIDC user account, I cannot access some endpoints:
GETthe list of projects, but I cannotGETa specific project.GETthe list of repositories in a project, but I cannotGETa specific repository.GETthe list of artifacts in a repository, but I cannotGETa specific artifact (or e.g. its vulnerabilities).Specifically, when using curl, I get a 401 response with this body:
{"errors":[{"code":"UNAUTHORIZED","message":"unauthorized"}]}I can access all endpoints with curl using a robot account or the admin account (which do not use OIDC).
I can also access all endpoints in the web GUI and the API Explorer (
/devcenter-api-2.0) using my OIDC account.Steps to reproduce the problem
Output:
Lines like this one show up in the log:
The error is thrown here.
Additional information
Notably, it turns out that in the web GUI and the API Explorer, a cookie named
sidis included in each request. That cookie alone turns out to be enough for authentication and authorization – theAuthorizationheader (i.e. curl's-uflag) is not even needed:As previously stated, the cookie is necessary for some endpoints (when accessed by an OIDC user). However, the API Explorer generates commands like this one, without any cookie:
All in all, there seems to be some inconsistency regarding OIDC authentication:
/projects/foo) require an OIDC cookie, while others (e.g./projects) do not.Versions