-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Create a new Keycloak implementation as a copy of Cognito * Strip out Cognito specifics * Create a new client using DCR * Reimplement create without DCR; implement delete; document auth * Additional test for deletes * Get tokens from a helper function * Enable authorization services on new clients * Get tokens with middleware * Use management client as resource server and discover endpoints * Authorise API products via resources and permissions * Document Keycloak setup and policy enforcement * Tests for permissions management * Remove reference to Keycloak resource server * fix dev release * fix dev release - add fallback for release tag * add keycloak variables in values template * add id to keycloak oauth credential creation, cognito TODO * update openapi definition * add id to e2e tests * fix unit tests * remove name from client generation * fix tests using new id field * Return created client's name for id * add GetAPIProducts endpoint + Keycloak implementation * add GetAPIProducts handler tests * fix github linter problem * github review comment fixes * update Keycloak's UpdateAppAPIProducts method to CRUD as-needed * update README wording * update example scope --------- Co-authored-by: Fabian Gonzalez <[email protected]>
- Loading branch information
1 parent
80aaae6
commit c227bca
Showing
28 changed files
with
1,877 additions
and
320 deletions.
There are no files selected for viewing
This file contains 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 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 |
---|---|---|
|
@@ -17,3 +17,6 @@ _helm_sync_dir/ | |
|
||
helm/Chart.yaml | ||
helm/values.yaml | ||
|
||
# Built binaries | ||
cmd/idp-connect |
This file contains 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 |
---|---|---|
@@ -1,17 +1,112 @@ | ||
## Development | ||
# Development | ||
|
||
This is a development guide for users wanting to help contribute to the project. | ||
|
||
## Environment | ||
|
||
Before you begin, make sure you have all of the required tools installed: | ||
|
||
``` | ||
```sh | ||
./env/validate-env.sh | ||
``` | ||
|
||
## TODO: | ||
Add any new connector implementations to `cmd/idp-connect.go` so that they can become valid server options to start. | ||
|
||
## Keycloak | ||
|
||
You can test the manipulation of self-service clients using a dedicated realm in a Keycloak instance. Create a new realm using curl and the admin credentials using the examples below. | ||
|
||
First, create a token to access the Keycloak REST API. This is a short-lived token, so you may need to repeat this step later on: | ||
|
||
```sh | ||
KEYCLOAK_URL=http://$(kubectl --context mgmt -n keycloak get service keycloak -o jsonpath='{.status.loadBalancer.ingress[0].*}'):8080 | ||
|
||
KEYCLOAK_TOKEN=$(curl -Ssm 10 --fail-with-body \ | ||
-d "client_id=admin-cli" \ | ||
-d "username=admin" \ | ||
-d "password=admin" \ | ||
-d "grant_type=password" \ | ||
"$KEYCLOAK_URL/realms/master/protocol/openid-connect/token" | | ||
jq -r .access_token) | ||
``` | ||
|
||
Create the new realm: | ||
|
||
```sh | ||
REALM=my-realm | ||
|
||
curl -Ssm 10 --fail-with-body -H "Authorization: Bearer ${KEYCLOAK_TOKEN}" -H "Content-Type: application/json" \ | ||
-d '{ "realm": "'${REALM}'", "enabled": true }' \ | ||
$KEYCLOAK_URL/admin/realms | ||
``` | ||
|
||
You'll need to provision a client in this realm that permits service accounts and has permissions to manipulate self-service clients. For convenience, we'll also treat this client as a _resource server_ in which we will store API products as _resources_. You can create such a client like this: | ||
|
||
```sh | ||
KEYCLOAK_CLIENT=gloo-portal | ||
|
||
# Create initial token to register the client | ||
INITIAL_TOKEN=$(curl -Ssm 10 --fail-with-body -H "Authorization: Bearer ${KEYCLOAK_TOKEN}" -H "Content-Type: application/json" \ | ||
-d '{ "expiration": 0, "count": 1 }' \ | ||
$KEYCLOAK_URL/admin/realms/${REALM}/clients-initial-access | | ||
jq -r .token) | ||
|
||
# Register the client | ||
read -r KEYCLOAK_CLIENT_INTERNAL_ID KEYCLOAK_SECRET <<<$(curl -Ssm 10 --fail-with-body -H "Authorization: bearer ${INITIAL_TOKEN}" -H "Content-Type: application/json" \ | ||
-d '{ "clientId": "'${KEYCLOAK_CLIENT}'", "name": "Solo.io Gloo Portal Resource Server" }' \ | ||
${KEYCLOAK_URL}/realms/${REALM}/clients-registrations/default | | ||
jq -r '[.id, .secret] | @tsv') | ||
|
||
echo "Management client ID: ${KEYCLOAK_CLIENT}" | ||
echo "Management client secret: ${KEYCLOAK_SECRET}" | ||
|
||
# Set up the client as we need | ||
curl -Ssm 10 --fail-with-body -H "Authorization: Bearer ${KEYCLOAK_TOKEN}" -H "Content-Type: application/json" \ | ||
-X PUT -d '{ "serviceAccountsEnabled": true, "authorizationServicesEnabled": true }' \ | ||
${KEYCLOAK_URL}/admin/realms/${REALM}/clients/${KEYCLOAK_CLIENT_INTERNAL_ID} | ||
|
||
# Get the internal ID of the client's service account user | ||
SA_USER_ID=$(curl -Ssm 10 --fail-with-body -H "Authorization: Bearer ${KEYCLOAK_TOKEN}" -H "Content-Type: application/json" \ | ||
${KEYCLOAK_URL}/admin/realms/${REALM}/clients/${KEYCLOAK_CLIENT_INTERNAL_ID}/service-account-user | | ||
jq -r .id) | ||
|
||
# Get the ID of the 'realm-management' client | ||
REALM_MGMT_CLIENT_ID=$(curl -Ssm 10 --fail-with-body -H "Authorization: Bearer ${KEYCLOAK_TOKEN}" \ | ||
"${KEYCLOAK_URL}/admin/realms/${REALM}/clients?clientId=realm-management" | | ||
jq -r '.[].id') | ||
|
||
# Get the ID of the 'manage-clients' role | ||
ROLE_ID=$(curl -Ssm 10 --fail-with-body -H "Authorization: Bearer ${KEYCLOAK_TOKEN}" -H "Content-Type: application/json" \ | ||
${KEYCLOAK_URL}/admin/realms/${REALM}/users/${SA_USER_ID}/role-mappings/clients/${REALM_MGMT_CLIENT_ID}/available | jq -r '.[] | select(.name=="manage-clients") | .id') | ||
|
||
# Add the 'manage-clients' role to the service account user | ||
curl -Ssm 10 --fail-with-body -H "Authorization: Bearer ${KEYCLOAK_TOKEN}" -H "Content-Type: application/json" \ | ||
-d '[ { "id": "'${ROLE_ID}'", "name": "manage-clients", "composite": false, "clientRole": true, "containerId": "'${REALM_MGMT_CLIENT_ID}'" } ]' \ | ||
${KEYCLOAK_URL}/admin/realms/${REALM}/users/${SA_USER_ID}/role-mappings/clients/${REALM_MGMT_CLIENT_ID} | ||
``` | ||
|
||
The values of `KEYCLOAK_CLIENT` and `KEYCLOAK_SECRET` should be supplied to the Keycloak flavour of `idp-connect` at runtime (via `--client-id` and `--client-secret`) so that the service can obtain tokens and manipulate self-service clients on behalf of this management client. In the example used so far, you can start the service like this: | ||
|
||
```sh | ||
./idp-connect keycloak --issuer ${KEYCLOAK_URL}/realms/${REALM} --client-id ${KEYCLOAK_CLIENT} --client-secret ${KEYCLOAK_SECRET} | ||
``` | ||
|
||
IDP Connect will use the token endpoint to obtain a token for the management client. You can replicate this for testing purposes like this: | ||
|
||
```sh | ||
MGMT_TOKEN=$(curl -Ssm 10 --fail-with-body \ | ||
-u ${KEYCLOAK_CLIENT}:${KEYCLOAK_SECRET} \ | ||
-d "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket" \ | ||
-d "audience=${KEYCLOAK_CLIENT}" \ | ||
${KEYCLOAK_URL}/realms/${REALM}/protocol/openid-connect/token | | ||
jq -r .access_token) | ||
|
||
# Test the token by listing the clients in the realm | ||
curl -Ssm 10 --fail-with-body -H "Authorization: Bearer ${MGMT_TOKEN}" ${KEYCLOAK_URL}/admin/realms/${REALM}/clients | jq . | ||
``` | ||
|
||
## TODO | ||
|
||
* Create middleware to handle login requests and responses and exposing those metrics via Prometheus metrics | ||
* Cognito | ||
* Develop auth mechanism when Cognito is running in EKS, taking advantage of AWS IAM Role for Service Accounts | ||
* Develop auth mechanism when Cognito is running in EKS, taking advantage of AWS IAM Role for Service Accounts |
This file contains 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 |
---|---|---|
@@ -1,19 +1,37 @@ | ||
# IDP Connect | ||
|
||
IDP Connect is an implementation of the Service Programming Interface Gloo Platform Portal uses in order to manage client credentials for accessing services in your Kubernetes Cluster. In Gloo Platform Portal, we use the concept of "Applications" to refer to the external applications accessing the API Products exposed via your Gloo Portal. When a user registers an application as an OAuth client, | ||
it is the responsibility of the SPI to create the credential associated with that application. For more information, and to review key terms associated with Gloo Platform Portal, checkout out our documentation: [Gloo Portal Documentation](https://docs.solo.io/gloo-portal/latest/). | ||
IDP Connect is an implementation of the Service Programming Interface Gloo Gateway Portal uses in order to manage client credentials for accessing services in your Kubernetes Cluster. In Gloo Gateway Portal, we use the concept of "Applications" to refer to the external applications accessing the API Products exposed via your Gloo Portal. When a user registers an application as an OAuth client, | ||
it is the responsibility of the SPI to create the credential associated with that application. For more information, and to review key terms associated with Gloo Gateway Portal, checkout out our documentation: [Gloo Portal Documentation](https://docs.solo.io/gloo-portal/latest/). | ||
|
||
## Supported Identity Providers | ||
|
||
Here is a list of Identity Providers that we currently support: | ||
|
||
* Amazon Cognito | ||
* Keycloak | ||
|
||
## Configuration Instructions | ||
|
||
### Keycloak | ||
|
||
A Keycloak client must be created for the Keycloak IDP Connect service to use. Provide the ID and secret of this client in the `--client-id` and `--client-secret` IDP Connect arguments respectively. This client must meet some requirements: | ||
|
||
* The client must have the `manage-client` permission needed for IDP Connect to be able to manipulate self-service clients. | ||
* **Authorization** must be enabled on this client, as this client will also act as an OAuth2 [resource server](https://www.keycloak.org/docs/latest/authorization_services/index.html#_resource_server_overview). | ||
* **Service accounts roles** (or OAuth2 _client credentials_) must be enabled, to allow IDP Connect to use this client directly to manage other clients and resources. | ||
|
||
#### Related documentation | ||
|
||
* Keycloak's support for client registration: <https://www.keycloak.org/docs/latest/securing_apps/#_client_registration> | ||
* Resource authorization in Keycloak: <https://www.keycloak.org/docs/latest/authorization_services/> | ||
* IDP Connect will manipulate resources using Keycloak's Authorization Services, which is based on [User-Managed Access (UMA)](https://docs.kantarainitiative.org/uma/rec-uma-core.html) | ||
|
||
## Production | ||
|
||
IDP Connect provides a straightforward and easy-to-setup way of configuring credentials for the applications in your system; however, | ||
we expect that the needs of your system are and will evolve beyond the scope of this simple implementation. The SPI we provide provides a hook on top of which you can build a customizable system to service any number of more advanced use cases. | ||
|
||
TODO: Add information for devs | ||
|
||
* Install tools | ||
* (Potential) Allow for AWS IAM Roles for service accounts as cognito auth method. | ||
* (Potential) Allow for AWS IAM Roles for service accounts as cognito auth method. |
This file contains 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 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 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.