Skip to content

Use starlette permissions to verify endpoint scopes

Nikola Milojevic requested to merge 426572-add-permissions-for-scopes into main

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

  1. Checkout this branch

  2. Run https://gitlab.com/gitlab-org/customers-gitlab-com on local environment (localhost:5000)

  3. Checkout 426572-oidc-provider-audience-support for CustomersDot, introduced in https://gitlab.com/gitlab-org/customers-gitlab-com/-/merge_requests/8439

  4. 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
  5. 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
  6. Run model gateway

      poetry run ai_gateway
  7. 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"
        }
      }'
  8. 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:

  1. 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)

Edited by Nikola Milojevic

Merge request reports