feat: Cloud Connector Auth
Description
This MR resolves Duo Workflow Service: Cloud Connector Auth (duo-workflow-executor#4 - closed) by adding the following capability to Duo Workflow Service:
- Authenticate incoming requests by checking
authorizationheader's bearer token. Decode the token by JWKS fetched from GitLab.com or Customer Dot. Seeduo_workflow_service/auth/intercepters.pyfor more information. - Authorize the access by checking
scopesclaim of the decoded JWT. Likely checkingduo_workflow_serviceunit primitive. - Introduce a new RPC to generate User-level JWT.
TokenAuthorityis responsible to generate it.
This is for quickly unblocking Duo Workflow Service launch that is scheduled at mid August.
Duplicate Auth code of AI Gateway
This MR duplicates most of the auth logic from AI Gateway. In fact, auth module namespace is almost intact with a few modification to remove FastAPI/Starlette specific code.
This is a good exercise to extract Cloud Connector module, which effectively addresses [AI Gateway] Bunlde up CC auth logic in a singl... (gitlab-org/modelops/applied-ml/code-suggestions/ai-assist#537 - closed). Later, we would introduce a Cloud Connector Python client by moving these duplicated CC logic to there, and use it in AI Gateway project as well. It's worth noting that the refactoring work won't block Duo Workflow Service launch.
Test locally
Run Duo Workflow Service (server):
poetry run python -m duo_workflow_service.server
Test Local Authority Auth
You need to copy .env.example into .env to make the key pair available for signing the token.
Test a client request:
poetry run python -m duo_workflow_service.client
Test GitLab OIDC
To test GitlabOIDC, point gitlab_url to your GDK, example: gitlab_url: str = "http://localhost:3000"
Also, you need a valid, GitLab-issued token.
To get, run rails console in GitLab-Rails and execute:
::Gitlab::CloudConnector::SelfIssuedToken.new(audience: "gitlab-duo-workflow-service", subject: Gitlab::CurrentSettings.uuid, scopes: ["duo_workflow_get_user_token"]).encoded
NB: This will last 1h, so you can hack EXPIRES_IN in https://gitlab.com/gitlab-org/gitlab/blob/7409472bbbcd2d30e4641eae3c99fd2ab52731ac/ee/lib/gitlab/cloud_connector/self_issued_token.rb#L7 before running the command. I put it to 1.month.
Then set it into DUO_WORKFLOW_CLIENT_TOKEN so it will be available at the same context as you run poetry run python -m duo_workflow_service.client.
Uncomment out this section and comment "Local authority section": !12 (diffs)
Additional information
See duo_workflow_service/client.py for more information. also README.md.