-
Notifications
You must be signed in to change notification settings - Fork 106
feat(bff): introduce support of multiple auth methods (internal, user_token) #918
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 4 commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
236080d
feat(bff): introduce support of multiple auth methods (internal, user…
ederign c99f7cc
feat(bff): looks like we don't need to override the certs
ederign da5e981
Fixes after code review by Christian
ederign c74a659
fixing mock factory creation (removing real client creation but still…
ederign 1a27427
Adding back clusterAdmin to user, implement it to token, and also ext…
ederign 6eb73ac
feat(auth): make token header and prefix configurable via flags and env
ederign File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,7 +24,7 @@ The main difference between the two docker compose files is that `-local` one bu | |
|
||
When shutting down the docker compose, you might want to clean-up the SQLite db file generated by ML Metadata, for example `./test/config/ml-metadata/metadata.sqlite.db` | ||
|
||
# Development | ||
## Development | ||
|
||
Run the following command to build the BFF: | ||
|
||
|
@@ -61,7 +61,17 @@ make lint | |
|
||
For more information on configuring golangci-lint see the [documentation](https://golangci-lint.run/). | ||
|
||
# Building and Deploying | ||
## Running the linter locally | ||
The BFF directory uses golangci-lint to combine multiple linters for a more comprehensive linting process. To install and run simply use: | ||
|
||
```shell | ||
cd clients/ui/bff | ||
make lint | ||
``` | ||
|
||
For more information on configuring golangci-lint see the [documentation](https://golangci-lint.run/). | ||
|
||
## Building and Deploying | ||
|
||
Run the following command to build the BFF: | ||
|
||
|
@@ -88,25 +98,25 @@ See the [OpenAPI specification](../api/openapi/mod-arch.yaml) for a complete lis | |
You will need to inject your requests with a `kubeflow-userid` header and namespace for authorization purposes. | ||
|
||
When running the service with the mocked Kubernetes client (MOCK_K8S_CLIENT=true), the user `[email protected]` is preconfigured with the necessary RBAC permissions to perform these actions. | ||
|
||
``` | ||
# GET /v1/healthcheck | ||
curl -i -H "kubeflow-userid: [email protected]" "localhost:4000/api/v1/healthcheck" | ||
# GET /v1/healthcheck | ||
curl -i "localhost:4000/healthcheck" | ||
``` | ||
``` | ||
|
||
``` | ||
# GET /v1/user | ||
# GET /v1/user | ||
curl -i -H "kubeflow-userid: [email protected]" "localhost:4000/api/v1/user" | ||
curl -i -H "X-Forwarded-Access-Token: $TOKEN" "localhost:4000/api/v1/user" | ||
``` | ||
|
||
``` | ||
# GET /v1/namespaces (only works when DEV_MODE=true) | ||
curl -i -H "kubeflow-userid: [email protected]" "localhost:4000/api/v1/namespaces" | ||
curl -i -H "X-Forwarded-Access-Token: $TOKEN" "localhost:4000/api/v1/namespaces" | ||
``` | ||
|
||
``` | ||
# GET /v1/model_registry | ||
curl -i -H "kubeflow-userid: [email protected]" "localhost:4000/api/v1/model_registry?namespace=kubeflow" | ||
curl -i -H "X-Forwarded-Access-Token: $TOKEN" "localhost:4000/api/v1/model_registry?namespace=kubeflow" | ||
``` | ||
|
||
``` | ||
|
@@ -120,6 +130,7 @@ curl -i \ | |
``` | ||
# GET /v1/model_registry/{model_registry_id}/registered_models | ||
curl -i -H "kubeflow-userid: [email protected]" "localhost:4000/api/v1/model_registry/model-registry/registered_models?namespace=kubeflow" | ||
curl -i -H "X-Forwarded-Access-Token: $TOKEN" "localhost:4000/api/v1/model_registry/model-registry-service/registered_models?namespace=kubeflow-user-example-com"" | ||
``` | ||
|
||
``` | ||
|
@@ -360,24 +371,38 @@ The mock Kubernetes environment is activated when the environment variable `MOCK | |
- `non-model-registry`: resides in the `kubeflow` namespace _without_ the label `component: model-registry`. | ||
- `model-registry-dora`: resides in the `dora-namespace` namespace with the label `component: model-registry`. | ||
|
||
#### 3. How BFF authorization works for kubeflow-userid and kubeflow-groups? | ||
#### 3. Which Authentication methods are supported? | ||
|
||
The BFF supports two authentication modes, selectable via the --auth-method flag or AUTH_METHOD environment variable (default: internal): | ||
|
||
Authorization is performed using Kubernetes SubjectAccessReview (SAR), which validates user access to resources. | ||
- `internal`: Uses the credentials of the running backend. | ||
- If running inside the cluster, it uses the pod’s service account. | ||
- If running locally (e.g. for development), it uses the current user's active kubeconfig context. | ||
- In this mode, user identity is passed via the kubeflow-userid and optionally kubeflow-groups headers. | ||
- This is the default mode and works well with mock clients and local testing. | ||
- `user_token`: Uses a user-provided Bearer token for authentication. | ||
- The token must be passed in the `X-Forwarded-Access-Token` header. | ||
- Useful when the frontend is fronted by an auth proxy (e.g., Istio + OIDC) that injects a valid Kubernetes token. | ||
|
||
- `kubeflow-userid`: Required header that specifies the user’s email. Access is checked directly for the user via SAR. | ||
- `kubeflow-groups`: Optional header with a comma-separated list of groups. If the user does not have access, SAR checks group permissions using OR logic. If any group has access, the request is authorized. | ||
|
||
Access to Model Registry List: | ||
#### 4. How BFF authorization works? | ||
|
||
- To list all model registries (/v1/model_registry), we perform a SAR check for get and list verbs on services within the specified namespace. | ||
- If the user or any group has permission to get and list services in the namespace, the request is authorized. | ||
Authorization is performed using Kubernetes access reviews, validating whether the user (or their groups) can perform certain actions. | ||
There are two review mechanisms depending on the authentication mode: | ||
- Internal mode (auth-method=internal): | ||
Uses SubjectAccessReview (SAR) to check whether the impersonated user (from kubeflow-userid and kubeflow-groups headers) has the required permissions. | ||
- User token mode (auth-method=user_token): Uses SelfSubjectAccessReview (SSAR), leveraging the Bearer token provided in the X-Forwarded-Access-Token header to check the current user's permissions directly. | ||
|
||
Access to Specific Model Registry Endpoints: | ||
##### Authorization logic | ||
* Access to Model Registry List (/v1/model_registry): | ||
- Checks for get and list on services in the target namespace. | ||
- If the user (or groups, in internal mode) has permission, access is granted. | ||
|
||
- For other endpoints (e.g., /v1/model_registry/{model_registry_id}/...), we perform a SAR check for get and list verbs on the specific service (identified by model_registry_id) within the namespace. | ||
- If the user or any group has permission to get or list the specific service, the request is authorized. | ||
* Access to Specific Model Registry Endpoints (/v1/model_registry/{model_registry_id}/...): | ||
- Checks for get on the specific service (identified by model_registry_id) in the namespace. | ||
- If authorized, access is granted. | ||
|
||
#### 4. How do I allow CORS requests from other origins | ||
#### 5. How do I allow CORS requests from other origins | ||
|
||
When serving the UI directly from the BFF there is no need for any CORS headers to be served, by default they are turned off for security reasons. | ||
|
||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.