Expose and secure a workload with OAuth2
This tutorial shows how to expose and secure services or Functions using API Gateway Controller. The controller reacts to an instance of the APIRule custom resource (CR) and creates an Istio VirtualService and Oathkeeper Access Rules according to the details specified in the CR. To interact with the secured services, the tutorial uses an OAuth2 client registered through the Hydra Maester controller.
You can use it as a follow-up to the Set up a custom domain for a workload tutorial.
Prerequisites
This tutorial is based on a sample HttpBin service deployment and a sample Function. To deploy or create one of those, follow the Create a workload tutorial.
Register an OAuth2 client and get tokens
Export your client as an environment variable:
Click to copyexport CLIENT_NAME={YOUR_CLIENT_NAME}Create an OAuth2 client with "read" and "write" scopes. Run:
Click to copycat <<EOF | kubectl apply -f -apiVersion: hydra.ory.sh/v1alpha1kind: OAuth2Clientmetadata:name: $CLIENT_NAMEnamespace: $NAMESPACEspec:grantTypes:- "client_credentials"scope: "read write"secretName: $CLIENT_NAMEEOFExport the credentials of the created client as environment variables. Run:
Click to copyexport CLIENT_ID="$(kubectl get secret -n $NAMESPACE $CLIENT_NAME -o jsonpath='{.data.client_id}' | base64 --decode)"export CLIENT_SECRET="$(kubectl get secret -n $NAMESPACE $CLIENT_NAME -o jsonpath='{.data.client_secret}' | base64 --decode)"Encode your client credentials and export them as an environment variable:
Click to copyexport ENCODED_CREDENTIALS=$(echo -n "$CLIENT_ID:$CLIENT_SECRET" | base64)Get tokens to interact with secured resources using client credentials flow:
- Token with "read" scope
- Token with "write" scope
Export the following value as an environment variable:
Click to copyexport KYMA_DOMAIN={KYMA_DOMAIN_NAME}Get the token:
Click to copycurl -ik -X POST "https://oauth2.$KYMA_DOMAIN/oauth2/token" -H "Authorization: Basic $ENCODED_CREDENTIALS" -F "grant_type=client_credentials" -F "scope=read"Export the issued token as an environment variable:
Click to copyexport ACCESS_TOKEN_READ={ISSUED_READ_TOKEN}
Expose and secure your workload
Follow the instructions in the tabs to expose an instance of the HttpBin service or a sample Function, and secure them with Oauth2 scopes.
- HttpBin
- Function
Export the following value as an environment variable:
Click to copyexport DOMAIN_TO_EXPOSE_WORKLOADS={DOMAIN_NAME}export GATEWAY=$NAMESPACE/httpbin-gatewayNOTE:
DOMAIN_NAME
is the domain that you own, for example, api.mydomain.com. If you don't want to use your custom domain, replaceDOMAIN_NAME
with a Kyma domain and$NAMESPACE/httpbin-gateway
with Kyma's default Gatewaykyma-system/kyma-gateway
Expose the service and secure it by creating an APIRule CR in your Namespace. Run:
Click to copycat <<EOF | kubectl apply -f -apiVersion: gateway.kyma-project.io/v1beta1kind: APIRulemetadata:name: httpbinnamespace: $NAMESPACEspec:gateway: $GATEWAYhost: httpbin.$DOMAIN_TO_EXPOSE_WORKLOADSservice:name: httpbinport: 8000rules:- path: /.*methods: ["GET"]accessStrategies:- handler: oauth2_introspectionconfig:required_scope: ["read"]- path: /postmethods: ["POST"]accessStrategies:- handler: oauth2_introspectionconfig:required_scope: ["write"]EOFNOTE: If you are running Kyma on k3d, add
httpbin.kyma.local
to the entry with k3d IP in your system's/etc/hosts
file.The exposed service requires tokens with "read" scope for
GET
requests in the entire service, and tokens with "write" scope forPOST
requests to the/post
endpoint of the service.
CAUTION: When you secure a workload, don't create overlapping Access Rules for paths. Doing so can cause unexpected behavior and reduce the security of your implementation.
Access the secured resources
Follow the instructions in the tabs to call the secured service or Functions using the tokens issued for the client you registered.
- Call secured endpoints of a service
- Call the secured Function
Send a
GET
request with a token that has the "read" scope to the HttpBin service:Click to copycurl -ik -X GET https://httpbin.$DOMAIN_TO_EXPOSE_WORKLOADS/headers -H "Authorization: Bearer $ACCESS_TOKEN_READ"Send a
POST
request with a token that has the "write" scope to the HttpBin's/post
endpoint:Click to copycurl -ik -X POST https://httpbin.$DOMAIN_TO_EXPOSE_WORKLOADS/post -d "test data" -H "Authorization: bearer $ACCESS_TOKEN_WRITE"These calls return the code
200
response. If you call the service without a token, you get the code401
response. If you call the service or its secured endpoint with a token with the wrong scope, you get the code403
response.
TIP: To learn more about the security options, read the document describing authorization configuration.