Introduction
Machine-to-machine (M2M) communication has become increasingly prevalent in modern application architectures, where different systems and services need to interact securely. Traditional authentication and authorization methods, such as shared secrets or mTLS, suffer from many shortcomings, ranging from a lack of fine-grained control to performance considerations.
At SlashID, we support several ways to implement M2M and API authentication and authorization. One of the fastest and most effective methods is by leveraging OAuth 2.0 Client Credentials.
In this blog post, we’ll show you how to use SlashID to implement M2M authentication and authorization in a Kubernetes cluster.
Why OAuth 2.0 client credentials
M2M authentication and authorization is still largely an open problem. Over the years many attempts have been made to standardize the process from simple shared secrets to mTLS to SPIRE/SPIFFE. We believe that the OAuth 2.0 approach is superior for a few reasons:
-
Strong Security: Compared to using shared secrets or API keys, OAuth2 Client Credentials provides a more secure authentication mechanism. Access tokens are short-lived and can be easily revoked, reducing the risk of long-term exposure if a token is compromised. Additionally, client credentials are securely stored and managed within SlashID, minimizing the risk of credential leakage.
-
Granular Access Control: OAuth2 scopes enable fine-grained access control, allowing you to define specific permissions for different API resources. This ensures that machine clients only have access to the resources they need, following the principle of least privilege.
-
Layer 7 vs Layer 3: Enforcing authorization policies at the same layer as the application logic allows for better finer-grained authorization and easier monitoring.
-
Standards-based Approach: OAuth2 Client Credential is a widely adopted and standardized authentication and authorization flow. This further reduces the dependency on SlashID, any IdP can be used instead.
-
Interoperability: OAuth2 Client Credentials are supported by various tools, libraries, and frameworks, making it easier to integrate with different systems and languages. This interoperability allows for seamless integration of machine-to-machine authentication and authorization across diverse environments and technologies.
-
North-South and East-West: In addition to protecting east-west traffic, through this approach, we can easily protect user-facing APIs as well as shown in this blog post.
The setup
In this example, we have a simple Kubernetes cluster that looks like the picture below:
The frontend sends requests to the backend Gate service (gate-microservices
), which then dispatches requests as required to several services in the deployment.
Our goal is to allow requests to the echo service only if they come from the frontend service and deny them otherwise.
Introducing SlashID Gate OAuth 2.0 plugins
Gate has two OAuth 2.0 plugins, the OAuth 2.0 Token Creator and the OAuth 2.0 Token Validator. As their names suggest, one can be used to add an OAuth 2.0 access token to a request, and the other to validate an OAuth 2.0 token in an incoming request. Further through our plugins we can:
- Allow requests only from specific client ids
- Allow requests only from specific IP addresses
In our scenario, we leverage both to enable M2M authentication and authorization. In a simplified picture, this is the deployment we are aiming for:
Specifically, the backend-echo
service comes with a Gate sidecar that verifies OAuth 2.0 access tokens in incoming requests as shown below:
...
plugins:
- id: validate_oauth2_requests
type: validate-oauth2-token
enabled: false
parameters:
header_with_token: SlashID_Signature
token_introspection_client_id: 0661f429-e6d8-7619-a900-3122cb349922
token_introspection_client_secret: <secret>
token_format: opaque
token_introspection_url: "https://api.slashid.com/oauth2/tokens/introspect"
required_scopes:
- admin
allowed_client_ids:
- 0662337e-05b3-7fb5-ae00-b9119ba17644
allowed_ip_addresses:
- 172.26.0.8
...
urls:
# The /api/echo endpoint is used as a demonstration of the anonymizer and oauth 2.0 validator plugins
- pattern: "*/api/echo*"
target: http://localhost:8080
plugins:
validate_oauth2_requests:
enabled: true
This configuration requires a valid OAuth 2.0 access token generated from the client ID 0662337e-05b3-7fb5-ae00-b9119ba17644
with admin
as a scope for the request to reach the */api/echo*
endpoints coming from the IP address 172.26.0.8
.
On the sender side, the gate-web
instance is configured to add an OAuth 2.0 access token to all requests:
plugins:
- id: add_authnz
type: request-oauth2-authenticator
enabled: true
parameters:
slashid_api_key: {{ .env.SLASHID_API_KEY }}
slashid_org_id: {{ .env.SLASHID_ORG_ID }}
header_for_token: "SlashID_Signature"
oauth2_token_format: "opaque"
oauth2_token_creation_endpoint: "https://api.slashid.com/oauth2/tokens"
oauth2_token_client_id: "0662337e-05b3-7fb5-ae00-b9119ba17644"
oauth2_token_client_secret: <secret>
oauth2_scopes:
- admin
This is what a full, authenticated, roundtrip looks like - The sender adds the OAuth 2.0 access token to the request:
The receiver verifies the token before forwarding it to the backend service:
With this setup we can guarantee that only requests originating from the front end reach the echo backend, restricting access to a specific client id and IP address.
Beyond the sidecar model
What we’ve shown in this example is just one of the many topologies we can use Gate in, for instance, you could achieve the same result using Gate as an external authorizer for Istio/Envoy.
Further, as we’ve shown in a previous blog post the OAuth 2.0 request validator plugin can be combined with our powerful OpenAPI parser to automatically enforce OAuth 2.0 client credentials authentication and authorization on your user-facing APIs meaningfully increasing your API security posture compared to simple API keys which are hard to rotate, can’t be used for authorization and are long-lived.
Conclusion
In this blog post, we’ve shown how we can leverage Gate to implement M2M authentication and authorization using OAuth 2.0 client credentials. We’d love to hear any feedback you may have. Please contact us if you are interested in securing your APIs and machines.