- authenticate: added a token exchange api endpoint that converts an identity provider's JWT into a pomerium session. - internal/identity: authenticate now passes context. - internal/identity: removed extraneous GetSignInURL from okta. - internal/sessions: add rest store - update go.mod / go.sum depedencies. - docs: add programmatic examples in shell and python
3.9 KiB
title | description |
---|---|
Programmatic access | This article describes how to configure pomerium to be used to enable machine-to-machine programmatic access. |
Programmatic access
This page describes how to access Pomerium endpoints programmatically.
Configuration
Every identity provider has slightly different methods for issuing OAuth 2.0 access tokens suitable for machine-to-machine use, please review your identity provider's documentation. For example:
- Google Oauth2 2.0 for Desktop Apps
- Okta PKCE Flow
- Azure Active Directory using the OAuth 2.0 code grant flow
For the sake of illustration, this guide and example scripts will use Google as the underlying identity provider.
Identity Provider Configuration
To configure programmatic access for Pomerium we'll need to set up an additional OAuth 2.0 client ID that can issue id_tokens
whose audience matches the Client ID of Pomerium. Follow these instructions adapted from Google's documentation:
- Go to the Credentials page.
- Select the project with the Pomerium secured resource.
- Click Create credentials, then select OAuth Client ID.
- Under Application type, select Other, add a Name, then click Create.
- On the OAuth client window that appears, note the client ID and client secret.
- On the Credentials window, your new Other credentials appear along with the primary client ID that's used to access your application.
High level flow
The application interacting with Pomerium will roughly have to manage the following access flow.
- A user authenticates with the OpenID Connect identity provider. This typically requires handling the Proof Key for Code Exchange process.
- Exchange the code from the Proof Key for Code Exchange for a valid
refresh_token
. - Using the
refresh_token
from the last step, request the identity provider issue a newid_token
which has our Pomerium app'sclient_id
as theaudience
. - Exchange the identity provider issued
id_token
for apomerium
token (e.g.https://authenticate.{your-domain}/api/v1/token
). - Use the pomerium issued
Token
authorization bearer token for all requests to Pomerium protected endpoints until it'sExpiry
. Authorization policy will be tied to the user as normal.
Expiration and revocation
Your application should handle token expiration. If the session expires before work is done, the identity provider issued refresh_token
can be used to create a new valid session by repeating steps 3 and on.
Also, you should write your code to anticipate the possibility that a granted refresh_token
may stop working. For example, a refresh token might stop working if the underlying user changes passwords, revokes access, or if the administrator removes rotates or deletes the OAuth Client ID.
Example Code
It's not as bad as it sounds. Please see the following minimal but complete examples.
Python
python scripts/programmatic_access.py --client-secret REPLACE_ME \
--client-id 851877082059-85tfqg9hlm8j9km5d9uripd0dvk72mvk.apps.googleusercontent.com \
--pomerium-client-id 851877082059-bfgkpj09noog7as3gpc3t7r6n9sjbgs6.apps.googleusercontent.com
<<< @/scripts/programmatic_access.py
Bash
<<< @/scripts/programmatic_access.sh