design auth mechanism for admin UI
To consider: Auth0 Okta keycloak hydra
Ory Hydra is completely open source (I think) so that should be top of the list.
NOTE: This current status is very much in a rough draft showing off my experiments at the moment. I will update it as things progress.
Advantages of Ory/Hydra
- strictly adheres to OAuth 2.0 and OpenID Connect standards
- lightweight and efficient solution for token management, which is nice for a microservices architecture
- Big focus on best security practices
- Ory has an active community
- Open Source and transparent
Approach
- implement a secure and standardized authorization code flow
- I believe we can skip the consent step in the proccess for user login (though I think Ory insists on not skipping it for first sign on)
- Currently just using the idea of a full_access scope
Current Progress
- Check out my branch:
sj/2200-admin-ui-auth - Hydra is running in a Docker container, connected to a locally hosted PostgreSQL database
- I've performed necessary database setups and migrations for Hydra
- An OAuth2 client for the Rafiki admin has been created, configured for the authorization code flow
- Additionally, I've implemented a basic dummy flow in our admin UI
Next Steps
- Finish managing the consent flow
- Consider what scopes to use
- Consider what user roles are required
- Exploring Ory Kratos Integration for the user identity management
- Get the Admin UI to correctly handle and validate the authentication tokens provided by Hydra
- Consider how this approach would align with securing the API calls - I think this will align well since we have granular control over what scopes users consent to which should align with our GNAP approach
- Get this all properly containerized in a docker-compose file
Note: I'm updating this document to reflect the current status:
Local Playground (Preferred setup)
pnpm localenv:compose up
And in the browser simply go to http://localhost:4444/oauth2/auth?response_type=code&client_id=cloud-nine-client&redirect_uri=http://localhost:3010/callback&scope=full_access&state=ab4R32wFF
Local Set Up
First set up the hydra database, e.g. in Postgresql
sudo -i -u postgres
psql
CREATE USER hydra WITH PASSWORD 'hydra_password'; CREATE DATABASE hydra; GRANT ALL PRIVILEGES ON DATABASE hydra TO hydra;
exit
Run the db migrations
docker run -it --rm \ --network="host" \ oryd/hydra \ migrate sql --yes postgres://hydra:hydra_password@localhost:5432/hydra"
Get the ory hydra docker container up
docker run --network="host" --name ory-hydra -e DSN=postgres://hydra:hydra_password@localhost:5432/hydra -e URLS_SELF_ISSUER=http://localhost:4444/ -e URLS_LOGIN=http://localhost:3005/login -e URLS_CONSENT=http://localhost:3005/consent -e SECRETS_SYSTEM=some-random-secret -e LOG_LEVEL=debug -e LOG_LEAK_SENSITIVE_VALUES=true oryd/hydra serve all -
-dev
Add client to the db
docker exec -it ory-hydra /bin/sh
hydra create oauth2-client --grant-type authorization_code --name rafiki-admin-client --redirect-uri http://localhost:3005 --response-type code --scope full_access --secret YourClientSecret --skip-consent --token-endpoint-auth-method client_secret_post --endpoint http://localhost:4445
This will give you a CLIENT ID.
TO DO: Add this client ID as an environment variable to HYDRA_CLIENT_ID
Set HYDRA_CLIENT_REDIRECT_URI to http://localhost:3005
Set SEED_FILE_LOCATION to packages/frontend/app/seed.yml
Create the seed.yml file with your client's ID
clients:
- id: 'YOUR_CLIENT_ID'
name: 'happy-life'
redirectUri: 'http://localhost:3005/callback'
Start the frontend in dev mode - pnpm --filter frontend dev
Then enter this URL into a browser with your CLIENT_ID: http://localhost:4444/oauth2/auth?response_type=code&client_id=CLIENT_ID&redirect_uri=http://localhost:3005&scope=full_access&state=ab4R32wFF
@JoblersTune Is there any other setup that needs to be done on the postgres instance? I had to manually create the hydra database and the hydra_user user but I'm stuck on what table it's looking for when it throws Unable to locate the table - I'm not sure what table I should try to insert:
level=error msg=Unable to initialize service registry. audience=application error=map[debug: message:Unable to locate the table reason: status:Internal Server Error status_code:500] service_name=Ory Hydra service_version=v2.2.0-rc.3
edit: this is happening when I run the first command in the Set up post.
My db set up was like this:
sudo -i -u postgres
psql
CREATE USER hydra_user WITH PASSWORD 'x@mpl3_p@ssw0rd'; CREATE DATABASE hydra; GRANT ALL PRIVILEGES ON DATABASE hydra TO hydra_user;
exit
docker run -it --rm \ --network="host" \ oryd/hydra \ migrate sql --yes "postgres://hydra_user:x@mpl3_p@ssw0rd@localhost:5432/hydra"
I'll update the initial setup comment to be explicit.
If this doesn't resolve your issue then let me know.
Auth Flow
- Initial request to Hydra's authorization endpoint (http://hydra:4444/oauth2/auth) to start the OAuth flow with the necessary query parameters (response_type, client_id, redirect_uri and scope)
- The hydra instance write some cookies to the browser
- The hydra instance creates a session for the interaction
- The browser is redirected to the client's login provider with a login_challenge (should be Kratos but for now is http://localhost:3010/login). This is where the user will authenticate.
- The admin remix server calls the Hydra server using the cookies and identifiers for the session to get session information and set up the interaction on the front end
- Redirect after successful authentication to Hydra's admin endpoint to accept the login request (http://hydra:4445/admin/oauth2/auth/requests/login/accept) along with the login_challenge.
- If the login challenge is completed successfully, the remix server redirects the browser to its a configured consent endpoint which was registered with the client where the user can approve the requested permissions. This is accompanied by a consent_challenge.
- The admin remix server calls the Hydra server using the cookies and identifiers for the session to get session information and set up the interaction on the front end
- After consent is granted the Remix server indicates that to the Hydra's admin endpoint (http://hydra:4445/admin/oauth2/auth/requests/consent/accept) along with the consent_challenge.
- The browser is redirected to the client's configured callback URL with authorization code in the query parameters.
- The callback page handles the result of the consent and if it received an authorization code it exchanges it for an access token at Hydra's authorization endpoint (http://hydra:4444/oauth2/token)