Use starlette permissions to verify endpoint scopes
What does this merge request do and why?
In !421 (merged) we added support for new universal tokens.
The universal token has a custom claim defining scopes
.
This MR uses Starlette permissions to verify endpoint scopes
By adding claims.scopes
as AuthCredentials, we can now use request.auth.scopes
and require authentication scopes for our @routes.
See https://www.starlette.io/authentication/
Example:
@router.post("/completions", response_model=SuggestionsResponse)
@requires("code_suggestions")
async def completions(
...
In case that token contains different scope (i.e: :duo_chat
), this endpoint will return 403
How to set up and validate locally
-
Checkout this branch
-
Run https://gitlab.com/gitlab-org/customers-gitlab-com on local environment (localhost:5000)
-
Checkout
426572-oidc-provider-audience-support
for CustomersDot, introduced in https://gitlab.com/gitlab-org/customers-gitlab-com/-/merge_requests/8439 -
Get a JWT token by running the following command in rails console for local customers-gitlab-com main.
jwt_token = ::Auth::JsonWebToken.new( audience: ::Gitlab::AddOnPurchases::ServiceTokenService::JWT_AUDIENCE,, scopes: [:code_suggestoins] ).encode
-
Update the
.env
file in the root folder with the following variables.GITLAB_URL=http://localhost:3000 CUSTOMER_PORTAL_BASE_URL=http://localhost:5000/ AUTH_BYPASS_EXTERNAL=false # Testing & development USE_FAKE_MODELS=true FASTAPI_API_PORT=5052
-
Run model gateway
poetry run ai_gateway
-
Run a cURL command to check the authentication, using the
jwt_token
generated in Step 3.curl -vvv --request POST \ --url 'http://localhost:5052/v2/completions' \ --header 'X-Gitlab-Authentication-Type: oidc' \ --header 'Authorization: Bearer <jwt_token>' \ --header 'Content-Type: application/json' \ --data '{ "prompt_version": 1, "project_path": "awesome_project", "project_id": 23, "current_file": { "file_name": "main.py", "content_above_cursor": "\"\"\"\nImplement fastapi middleware to log all incoming requests\"\"\"\n", "content_below_cursor": "scoopy doo" } }'
-
You should get the response:
{"id":"id","model":{"engine":"","name":""},"object":"text_completion","created":1689862537,"choices":[{"text":"fake code suggestion from GitLab Codegen","index":0,"finish_reason":"length"}]}
To test 403 response
Step 4 will now look like this:
-
Get a JWT token by running the following command in rails console for local customers-gitlab-com main.
jwt_token = ::Auth::JsonWebToken.new( audience: ::Auth::JsonWebToken::JWT_AUDIENCE, scopes: [:non_code_suggestoins] ).encode
Merge request checklist
-
Tests added for new functionality. If not, please raise an issue to follow up. -
Documentation added/updated, if needed.
Related to #328 (closed)