Skip to content

Commit

Permalink
doc m2m-token
Browse files Browse the repository at this point in the history
  • Loading branch information
jkralik committed Jul 8, 2024
1 parent 7d23024 commit bef8a6e
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 11 deletions.
81 changes: 81 additions & 0 deletions content/en/docs/configuration/m2m-oauth-server.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
title: 'Machine to Machine OAuth Server'
description: 'Service configuration overview'
date: '2024-07-04'
categories: [configuration, deployment]
keywords: [configuration]
weight: 10
---

Machine to Machine OAuth Server(M2M OAuth Server) is used for generate API tokens to access the plgd services by another services. These tokens is acquired via client credentials flow with client assertion type JWT or secret in case of service.

## Docker Image

```bash
docker pull ghcr.io/plgd-dev/hub/m2m-oauth-server:latest
```

## YAML Configuration

A configuration template is available on [m2m-oauth-server/config.yaml](https://github.com/plgd-dev/hub/blob/main/m2m-oauth-server/config.yaml).

### Logging

| Property | Type | Description | Default |
| ---------- | -------- | -------------- | ------- |
| `log.level` | string | `Logging enabled from level.` | `"info"` |
| `log.encoding` | string | `Logging format. The supported values are: "json", "console"` | `"json"` |
| `log.stacktrace.enabled` | bool | `Log stacktrace.` | `false` |
| `log.stacktrace.level` | string | `Stacktrace from level.` | `"warn"` |
| `log.encoderConfig.timeEncoder` | string | `Time format for logs. The supported values are: "rfc3339nano", "rfc3339".` | `"rfc3339nano"` |

### HTTP API

HTTP API of the OAuth Server service as defined [here](https://github.com/plgd-dev/hub/blob/main/m2m-oauth-server/uri/uri.go)

| Property | Type | Description | Default |
| ---------- | -------- | -------------- | ------- |
| `apis.http.address` | string | `Listen specification <host>:<port> for http client connection.` | `"0.0.0.0:9100"` |
| `apis.http.readTimeout` | string | `The maximum duration for reading the entire request, including the body by the server. A zero or negative value means there will be no timeout.` | `8s` |
| `apis.http.readHeaderTimeout` | string | `The amount of time allowed to read request headers by the server. If readHeaderTimeout is zero, the value of readTimeout is used. If both are zero, there is no timeout.` | `4s` |
| `apis.http.writeTimeout` | string | `The maximum duration before the server times out writing of the response. A zero or negative value means there will be no timeout.` | `16s` |
| `apis.http.idleTimeout` | string | `The maximum amount of time the server waits for the next request when keep-alives are enabled. If idleTimeout is zero, the value of readTimeout is used. If both are zero, there is no timeout.` | `30s` |
| `apis.http.tls.caPool` | []string | `File paths to the root certificates in PEM format. The file may contain multiple certificates.` | `[]` |
| `apis.http.tls.keyFile` | string | `File path to private key in PEM format.` | `""` |
| `apis.http.tls.certFile` | string | `File path to certificate in PEM format.` | `""` |
| `apis.http.tls.clientCertificateRequired` | bool | `If true, require client certificate.` | `true` |

### OAuth Signer

Signer configuration to access tokens of OAuth provider for services.

| Property | Type | Description | Default |
| ---------- | -------- | -------------- | ------- |
| `oauthSigner.privateKeyFile` | string | `File path to a private ECDSA key in PEM format required for access token signing.` | `""` |
| `oauthSigner.domain` | string | `Domain address <host>:<port> for OAuth APIs.` | `""`
| `oauthSigner.ownerClaim` | string | `Claim name in the token which contains the owner of the token.` | `"sub"` |
| `oauthSigner.deviceIDClaim` | string | `Claim name in the token which contains the deviceID of the token.` | `""` |
| `oauthSigner.clients[].id` | string | `client id which is used by oauth clients.` | `"test"` |
| `oauthSigner.clients[].secret` | string | `client secret which is used by oauth clients. Can be empty when .jwtPrivateKey is set` | `""` |
| `oauthSigner.clients[].accessTokenLifetime` | string | `validity of generated access token lifetime. 0s means forever.` | `"0s"` |
| `oauthSigner.clients[].allowedGrantTypes` | []string | `grant types which are allowed for the client. Only 'client_credentials' is supported.` | `[ "client_credentials" ]` |
| `oauthSigner.clients[].allowedAudiences` | []string | `audiences which are allowed for the client.` | `[]` |
| `oauthSigner.clients[].allowedScopes` | []string | `scopes which are allowed for the client.` | `[]` |
| `oauthSigner.clients[].insertTokenClaims` | object | `claims which are added to the token.` | `{}` |
| `oauthSigner.clients[].jwtPrivateKey.enabled` | bool | `allow JWT private key for client` | `false` |
| `oauthSigner.clients[].jwtPrivateKey.authorization.endpoints[].authority` | string | `address to OAuth authority` | `""` |
| `oauthSigner.clients[].jwtPrivateKey.authorization.endpoints[].maxIdleConns` | int | `It controls the maximum number of idle (keep-alive) connections across all hosts. Zero means no limit.` | `16` |
| `oauthSigner.clients[].jwtPrivateKey.authorization.endpoints[].maxConnsPerHost` | int | `It optionally limits the total number of connections per host, including connections in the dialing, active, and idle states. On limit violation, dials will block. Zero means no limit.` | `32` |
| `oauthSigner.clients[].jwtPrivateKey.authorization.endpoints[].maxIdleConnsPerHost` | int | `If non-zero, controls the maximum idle (keep-alive) connections to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used.` | `16` |
| `oauthSigner.clients[].jwtPrivateKey.authorization.endpoints[].idleConnTimeout` | string | `The maximum amount of time an idle (keep-alive) connection will remain idle before closing itself. Zero means no limit.` | `30s` |
| `oauthSigner.clients[].jwtPrivateKey.authorization.endpoints[].timeout` | string | `A time limit for requests made by this Client. A Timeout of zero means no timeout.` | `10s` |
| `oauthSigner.clients[].jwtPrivateKey.authorization.endpoints[].tls.caPool` | []string | `File paths to the root certificates in PEM format. The file may contain multiple certificates.` | `[]` |
| `oauthSigner.clients[].jwtPrivateKey.authorization.endpoints[].tls.keyFile` | string | `File path to private key in PEM format.` | `""` |
| `oauthSigner.clients[].jwtPrivateKey.authorization.endpoints[].tls.certFile` | string | `File path to certificate in PEM format.` | `""` |
| `oauthSigner.clients[].jwtPrivateKey.authorization.endpoints[].tls.useSystemCAPool` | bool | `If true, use system certification pool.` | `false` |

{{< note >}}

Note that the string type related to time (i.e. timeout, idleConnTimeout, expirationTime) is decimal numbers, each with optional fraction and a unit suffix, such as "300ms", "1.5h" or "2h45m". Valid time units are "ns", "us", "ms", "s", "m", "h".

{{< /note >}}
13 changes: 13 additions & 0 deletions content/en/docs/deployment/hub/advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,19 @@ helm upgrade -i -n plgd --create-namespace -f withMock.yaml hub plgd/plgd-hub

To configure the OAuth server, it is necessary to enable a redirect URL that permits any redirect within the domain for the web client. The web client utilizes redirects to display pages within the user interface (UI). For instance, when accessing `https://example.com/devices/{deviceId}` in the UI, the OAuth flow utilizes the opened URL as the redirect_uri. Therefore, it is essential to authorize `https://example.com/*` as a valid redirect URL to enable access to any subpage within the UI.

## Enable OAuth Service Client in m2m-oauth-server

To enable the OAuth service client for the m2m-oauth-server, provide the secret as follows:

```yaml
global:
m2mOAuthServer:
clientServiceSecret: |-
<OAUTH_CLIENT_SECRET>
```
This configuration creates an OAuth client with the ID `service`, as defined in the [helm values file](https://github.com/plgd-dev/hub/blob/fcf769cd3fe4b2e7a8e49fc27cc3c20ccb8b0153/charts/plgd-hub/values.yaml#L2630).

## Custom Authorization CA pool

By default, the plgd hub Helm chart expect that certificate used by OAuth 2.0 server is signed by the same CA as rest of certificates
Expand Down
38 changes: 27 additions & 11 deletions content/en/docs/deployment/hub/hub.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,58 @@ title: 'IoT Hub'
description: 'Running hub on Kubernetes'
docsOthersDisplay: true
date: '2021-11-01'
categories: [deployment, kubernetes]
keywords: [deployment, kubernetes, k8s, helm, chart]
categories:
- deployment
- kubernetes
keywords:
- deployment
- kubernetes
- k8s
- helm
- chart
weight: 10
isMainSectionPage: true
---

![Deployment diagram](/docs/deployment/hub/static/hub-deployment-diagram.drawio.svg "medium-zoom-image")

Quickest way how to install your own instance of the plgd hub is to use the Mock OAuth2.0 Server. With this option enabled, no authentication is available. The JWT token is automatically issued for the default user.
The quickest way to install your own instance of the plgd hub is to use the Mock OAuth2.0 Server. With this option enabled, no authentication is available, and a JWT token is automatically issued for the default user.

{{< warning >}}
The Mock OAuth Server should only be utilized for **testing** and **development purposes**. Exercise additional caution when using it! For production environments, please follow the deployment instructions provided in the [Advanced Configuration](/docs/deployment/hub/advanced) section to ensure proper setup.
The Mock OAuth Server should only be used for **testing** and **development purposes**. Exercise caution when using it! For production environments, follow the deployment instructions provided in the [Advanced Configuration](/docs/deployment/hub/advanced) section to ensure proper setup.
{{< /warning >}}

Before proceeding, generate a private key for `m2m-oauth-server`:

```sh
openssl ecparam -name prime256v1 -genkey -noout
```

Then, add the generated private key to the `m2mOAuthServer.privateKey` field in the `values.yaml` file:

```sh
echo "
global:
domain: \"example.com\"
hubId: \"d03a1bb4-0a77-428c-b78c-1c46efe6a38e\"
m2mOAuthServer:
privateKey: |-
<GENERATED_PRIVATE_KEY>
mockoauthserver:
enabled: true" > withMock.yaml

helm upgrade -i -n plgd --create-namespace -f withMock.yaml hub plgd/plgd-hub
```

{{< note >}}

To use `microk8s` or a similar kubernetes system, ensure that the `ingress`, `dns`, and `storage` add-ons are enabled. Additionally, configure your Kubernetes cluster to resolve the private domain `*.example.com` through the designated DNS server. For microk8s, use [microk8s enable dns:{DNS_SERVER}](https://microk8s.io/docs/addon-dns) to set up the DNS server.

If you are using `microk8s` or a similar Kubernetes system, ensure that the `ingress`, `dns`, and `storage` add-ons are enabled. Also, configure your Kubernetes cluster to resolve the private domain `*.example.com` through the designated DNS server. For `microk8s`, use [microk8s enable dns:{DNS_SERVER}](https://microk8s.io/docs/addon-dns) to set up the DNS server.
{{< /note >}}

Deployment of the plgd hub to the Kubernetes cluster is then initiated. Status of the deployment can be verified by calling `kubectl -n plgd get all`. When all pods are up and running, the plgd Dashboard will become available on your configured domain (e.g. `https://example.com`).
The deployment of the plgd hub to the Kubernetes cluster can now be initiated. Verify the status of the deployment using `kubectl -n plgd get all`. Once all pods are up and running, the plgd Dashboard will be accessible at your configured domain (e.g., `https://example.com`).

## NodePort for CoAP Gateway

If you install the plgd hub into [microk8s.io/](https://microk8s.io/), it is also required to enable nodePort for the CoAP Gateway Service and extend the port range of the K8S API Server. To extend the port range, add `--service-node-port-range=5683-32767` to `/var/snap/microk8s/current/args/kube-apiserver`. For the CoAP Gateway Service, apply following values:
If you are deploying the plgd hub on [microk8s.io/](https://microk8s.io/), you need to enable the NodePort for the CoAP Gateway Service and extend the port range of the K8S API Server. To extend the port range, add `--service-node-port-range=5683-32767` to `/var/snap/microk8s/current/args/kube-apiserver`. For the CoAP Gateway Service, apply the following values:

```yaml
coapgateway:
Expand All @@ -48,9 +64,9 @@ coapgateway:
```
{{< warning >}}
This configuration should only be applied in a test environment!
Apply this configuration only in a test environment!
{{< /warning >}}
## Deploying to Production
In order to deploy the Device Provisioning Service to a production environment, please refer to the [Advanced Configuration](/docs/deployment/hub/advanced) section for detailed instructions.
For deploying the Device Provisioning Service in a production environment, refer to the [Advanced Configuration](/docs/deployment/hub/advanced) section for detailed instructions.
35 changes: 35 additions & 0 deletions content/en/docs/features/control-plane/m2m-tokens.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
title: 'Machine to Machine Tokens'
description: 'What is a Machine to Machine token?'
date: '2024-07-05'
categories: [oauth]
keywords: [oauth, m2m, token]
weight: 70
---

The Machine to Machine OAuth Server (M2M OAuth Server) is used for generating API tokens to access plgd services by other services. These tokens are acquired via the client credentials flow with the client assertion type JWT or secret in the case of service. The tokens are exclusively used with plgd services.

## Why Use M2M Tokens?

Machine to Machine tokens are crucial for secure and efficient communication between services without human intervention. Here are some of the key benefits:

- **Security**: M2M tokens ensure that only authorized services can access your APIs, providing a secure way to manage access control.
- **Automation**: They enable automated workflows by allowing services to authenticate and authorize themselves, reducing the need for manual intervention.
- **Scalability**: M2M tokens facilitate the seamless scaling of services by allowing them to communicate and perform operations independently.
- **Efficiency**: Using M2M tokens can reduce latency and improve the performance of interactions between services since tokens are managed programmatically.

## How to Use M2M Tokens in plgd

In plgd, M2M tokens can be used for various purposes to enhance the functionality and security of your services. Here are some practical applications:

- **Device Provisioning**: M2M tokens are used for [automatic device provisioning](/docs/features/secured-onboarding-devices/secured-onboarding-devices/#automatic-device-provisioning), allowing you to onboard devices securely and efficiently.
- **Device Configuration**: After a device has been onboarded, M2M tokens enable you to [preconfigure devices](TODO) with the necessary settings.
- **Service Access**: If you have a service that needs to access plgd services, M2M tokens ensure secure and authorized interactions.

To start using M2M tokens, follow these steps:

1. **Obtain Client Credentials**: Register your service with the M2M OAuth Server to obtain the necessary client credentials (client ID and secret).
2. **Acquire Tokens**: Use the client credentials flow to acquire an M2M token. This involves sending a request to the OAuth server with your client credentials to receive an access token.
3. **Use Tokens for Authentication**: Include the acquired token in the authorization header of your API requests to authenticate and access plgd services.

By leveraging M2M tokens, you can enhance the security, automation, and efficiency of your service interactions with plgd, ensuring a robust and scalable integration.

0 comments on commit bef8a6e

Please sign in to comment.