# Configuration

## Keycloak

Once Keycloak has been deployed, a realm must be created (matching the values defined in the DS API configuration):

![Create Realm](/files/-MD-pGyoTEeP9W4oJmcn)

A client must also be created:

![Create Client](/files/-MD-pqVhwgjpDowNz-0R)

![Configure Client](/files/-MD-qJDp-s2t0cyLCWYq)

{% hint style="info" %}
Configure your client with the correct `Web Origins` and `Valid Redirect URIs` for your setup. If you wish to obtain access tokens via a password grant, enable `Direct Access Grants` and `Implicit Flow`. This may simplify obtaining tokens for an initial setup of the DS
{% endhint %}

In order for the `Kong` gateway to be able to validate the tokens issued by the realm client, the DS keystore must be configured as a `Key Provider`

![Add Keystore - Java Keystore](/files/-MD-rDBoi9ukrqcs_WBG)

![Configure Key Provider](/files/-MD-rOx2Zzh3yXDWrwDD)

When configuring the keystore, specify the keystore path (either mounted as a volume in your container or on the server filesystem) in the `Keystore` field. Also you **must** make sure the keystore has a higher `Priority` value than the other default providers.

{% hint style="warning" %}
The keystore must contain the same key pair as the keystore used by the DS API
{% endhint %}

After creating a user, you can obtain an access token using the implicit flow by performing the following request:

```bash
curl --location --request POST 'http://localhost:9999/auth/realms/trust1connector/protocol/openid-connect/token' \
    --header 'Content-Type: application/x-www-form-urlencoded' \
    --data-urlencode 'client_id=trust1connector' \
    --data-urlencode 'username=test@trust1team.com' \
    --data-urlencode 'password=test_password' \
    --data-urlencode 'grant_type=password'
```

This token can then be used to address the secured DS API endpoints

## Distribution Service API

The configuration of the Distribution Service API can be done entirely through environment variables, or directly by editing the `application.conf` which can be found in the `conf` folder in the server distributable. An overview of both configuration options can be found below.

### Configuration Options

| Key                                                         | Environment Variable                | Type    | Description                                                                                                                                                                                                                        |
| ----------------------------------------------------------- | ----------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| t1c-ds.general.**max-page-size**                            | DS\_MAX\_PAGE\_SIZE                 | Integer | The maximum allowed pagination size for results. This can be used in order to prevent the retrieval of too large a sample result. Default value is 100.                                                                            |
| t1c-ds.t1c.**domain**                                       | T1C\_DOMAIN                         | String  | The domain the T1C runs on.                                                                                                                                                                                                        |
| t1c-ds.t1c.**port**                                         | T1C\_PORT                           | Integer | The port the T1C runs on.                                                                                                                                                                                                          |
| t1c-ds.rmc.**label**                                        | RMC\_LABEL                          | String  | The application label that can be used by the RMC web application.                                                                                                                                                                 |
| t1c-ds.development.**include-stacktrace**                   | INCLUDE\_STACKTRACE                 | Boolean | Include a stacktrace in the application's JSON response, which can be useful for debugging purposes. **Must** be set to false in production environments                                                                           |
| t1c-ds.development.**require-gateway-headers**              | REQUIRE\_GATEWAY\_HEADERS           | Boolean | Incoming requests are checked for the presence of a `X-Consumer-Custom-ID` header placed by the gateway                                                                                                                            |
| t1c-ds.keystore.**path**                                    | DS\_KEYSTORE\_PATH                  | String  | The path (can be relative to the application root) to the DS API keystore in PKCS12 format, containing the DS certificate/keypair.                                                                                                 |
| t1c-ds.keystore.**password**                                | DS\_KEYSTORE\_PASSWORD              | String  | The password to the DS API keystore. This is sensitive information. We recommend storing it as an environment variable.                                                                                                            |
| t1c-ds.keystore.**alias**                                   | DS\_KEYSTORE\_ALIAS                 | String  | The alias of the DS API certificate/keypair stored in the keystore.                                                                                                                                                                |
| t1c-ds.security.**enabled**                                 | DS\_SECURITY\_ENABLED               | Boolean | Enables or disables the parsing of JSON web tokens on incoming requests. If set to false, all JWT payloads will be set to a default blank value. This **must** be set to true in production environments.                          |
| t1c-ds.security.jwt.**ds-issuer**                           | DS\_ISSUER                          | String  | The name of the DS API token issuer. It is used to generate JSON web tokens containing digests of configuration files.                                                                                                             |
| t1c-ds.security.jwt.**idp-issuer**                          | DS\_IDP\_ISSUER                     | String  | The name of the IDP token issuer. This is the value that can be found in the `iss` property in tokens issued by your configured IDP client. For Keyloak, this will take the form of `https://{{idp-url}}/auth/realms/{{realmId}}`. |
| t1c-ds.security.jwt.**registration-token-validity-seconds** | DS\_REG\_TOKEN\_VALIDITY\_SECONDS   | Integer | The seconds a token issued for a registration API key should remain valid.                                                                                                                                                         |
| t1c-ds.security.jwt.**application-token-validity-seconds**  | DS\_APP\_TOKEN\_VALIDITY\_SECONDS   | Integer | The seconds a token issued for a label API key should remain valid.                                                                                                                                                                |
| t1c-ds.gateway.**enabled**                                  | DS\_GATEWAY\_ENABLED                | Boolean | Set to false while developing in order to test the DS API without needing a Kong gateway to be available. **Must** be set to true for production environments.                                                                     |
| t1c-ds.gateway.**url**                                      | DS\_GATEWAY\_URL                    | String  | The `Kong` gateway URL. This value is used to generate download links for the Trust1Connector installer.                                                                                                                           |
| t1c-ds.gateway.**admin-url**                                | DS\_GATEWAY\_ADMIN\_URL             | String  | The Kong gateway admin API URL. This URL is used to dynamically create API keys for labels and versions.                                                                                                                           |
| t1c-ds.gateway.**ds-base-path**                             | DS\_GATEWAY\_BASE\_PATH             | String  | Used for generation of download links. If you route the DS on a non-default path, i.e. not on the root of the `Kong` gateway, you can specify it here. Default value is an empty string                                            |
| t1c-ds.gateway.config.consumers.**registration**            | DS\_GATEWAY\_CONSUMER\_REGISTRATION | String  | The `username` and `custom_id` of the registration consumer entity on the `Kong` gateway.                                                                                                                                          |
| t1c-ds.gateway.config.consumers.**application**             | DS\_GATEWAY\_CONSUMER\_APPLICATION  | String  | The `username`  and `custom_id` of the registration application entity on the `Kong` gateway.                                                                                                                                      |
| t1c-ds.gateway.config.consumers.**user**                    | DS\_GATEWAY\_CONSUMER\_USER         | String  | The `username` and `custom_id` of the registration consumer entity on the `Kong` gateway.                                                                                                                                          |
| slick.dbs.default.db.**url**                                | T1C\_DB\_URL                        | String  | The JNDI value for the PostgreSQL database to be used by the DS API, e. `jdbc:postgresql://localhost:5433/t1c-ds`                                                                                                                  |
| slick.dbs.default.db.**user**                               | T1C\_DS\_DB\_USER                   | String  | The PostgreSQL database username that has owner access to the `t1c-ds` database. We recommend storing this information as an environment variable.                                                                                 |
| slick.dbs.default.db.**password**                           | T1C\_DS\_DB\_PWD                    | String  | The PostgreSQL database user's password. We recommend storing this information as an environment variable.                                                                                                                         |
| play.evolutions.db.default.**enabled**                      | T1C\_EVOLUTIONS\_ENABLED            | Boolean | Toggle whether database evolutions are enabled. We recommend setting it to `false` in production environments and manually updating the database models with a script.                                                             |
| play.evolutions.db.default.**autoApply**                    | T1C\_EVOLUTIONS\_AUTO               | Boolean | Toggle whether database evolutions are automatically applied. We recommend setting it to `false` in production environments and manually updating the database models with a script.                                               |
| play.evolutions.db.default.**autoApplyDowns**               | T1C\_EVOLUTIONS\_AUTO\_DOWNS        | Boolean | Toggle whether database evolution downgrades are automatically applied. This **must** be set to `false` in production environments or data loss may occur.                                                                         |
| play.http.secret.**key**                                    | PLAY\_SECRET                        | String  | A secret used for built-in encryption utilities, signing session cookies and CSRF tokens, amongst other. This value **must** be set, and must be unique per environment.                                                           |
| pidfile.**path**                                            | PIDFILE\_PATH                       | String  | The path where the RUNNING\_PID file will be created. For dockerized environments, this must be set to `/dev/null`                                                                                                                 |

### Sample Configuration File

```javascript
# Version -> should match version in build.sbt
app.version = "3.0.0"

# Application specific config. Every property is duplicated with a value that can be read from the environment variables
# So that we can reuse the same config file in various environments
t1c-ds {
  general {
    max-page-size = 100
    max-page-size = ${?DS_MAX_PAGE_SIZE}
  }
  development {
    include-stacktrace = true
    include-stacktrace = ${?INCLUDE_STACKTRACE}
    require-gateway-headers = false
    require-gateway-headers = ${?REQUIRE_GATEWAY_HEADERS}
  }
  keystore {
    path = "conf/t1cds.p12"
    path = ${?DS_KEYSTORE_PATH}
    password = "v8%j22HVvHEiC9>e"
    password = ${?DS_KEYSTORE_PASSWORD}
    alias = "t1cds"
    alias = ${?DS_KEYSTORE_ALIAS}
  }
  security {
    enabled = false
    enabled = ${?DS_SECURITY_ENABLED}
    jwt {
      ds-issuer = "t1c-ds"
      ds-issuer = ${?DS_ISSUER}
      # For example
      # idp-issuer = "https://idp.t1t.io/auth/realms/trust1connector"
      idp-issuer = "http://localhost:9999/auth/realms/trust1connector"
      idp-issuer = ${?DS_IDP_ISSUER}
      registration-token-validity-seconds = 600
      registration-token-validity-seconds = ${?DS_REG_TOKEN_VALIDITY_SECONDS}
      application-token-validity-seconds = 600
      application-token-validity-seconds = ${?DS_APP_TOKEN_VALIDITY_SECONDS}
    }
  }
  gateway {
    enabled = true
    enabled = ${?DS_GATEWAY_ENABLED}
    url = "http://localhost:8000"
    url = ${?DS_GATEWAY_URL}
    admin-url = "http://localhost:8001"
    admin-url = ${?DS_GATEWAY_ADMIN_URL}
    # If the DS isn't hosted on the root of the gateway, set the path prefix here
    ds-base-path = ""
    ds-base-path = ${?DS_GATEWAY_BASE_PATH}
    config {
      consumers {
        registration = "t1cds-reg"
        application = "t1cds-app"
        user = "t1cds-user"
        registration = ${?DS_GATEWAY_CONSUMER_REGISTRATION}
        application = ${?DS_GATEWAY_CONSUMER_APPLICATION}
        user = ${?DS_GATEWAY_CONSUMER_USER}
      }
    }
  }
}

slick {
  db.default.logSql=true
  dbs.default.profile = "slick.jdbc.PostgresProfile$"
  dbs.default.db.driver = "org.postgresql.Driver"
  dbs.default.db.url = "jdbc:postgresql://localhost:5433/t1c-ds"
  dbs.default.db.url = ${?T1C_DB_URL}
  dbs.default.db.user = "postgres"
  dbs.default.db.user = ${?T1C_DS_DB_USER}
  dbs.default.db.password = "postgres"
  dbs.default.db.password = ${?T1C_DS_DB_PWD}
  # dbs.default.db.numThreads = 20
  # dbs.default.db.maxConnections = 20
}

## Evolutions
# https://www.playframework.com/documentation/latest/Evolutions
# ~~~~~
# Evolutions allows database scripts to be automatically run on startup in dev mode
# for database migrations. You must enable this by adding to build.sbt:
#
# libraryDependencies += evolutions
#
## Evolutions
play.evolutions {
  db.default.enabled = true
  db.default.autoApply = true
  db.default.autoApplyDowns = true
  schema = "public"
  db.default.enabled = ${?T1C_EVOLUTIONS_ENABLED}
  db.default.autoApply = ${?T1C_EVOLUTIONS_AUTO}
  db.default.autoApplyDowns = ${?T1C_EVOLUTIONS_AUTO_DOWNS}
  schema = ${?T1C_EVOLUTIONS_SCHEMA}
}

# This is the main configuration file for the application.
# https://www.playframework.com/documentation/latest/ConfigFile
# https://www.playframework.com/documentation/latest/Configuration
# ~~~~~
# Play uses HOCON as its configuration file format.  HOCON has a number
# of advantages over other config formats, but there are two things that
# can be used when modifying settings.
#
# You can include other configuration files in this main application.conf file:
#include "extra-config.conf"
#
# You can declare variables and substitute for them:
#mykey = ${some.value}
#
# And if an environment variable exists when there is no other subsitution, then
# HOCON will fall back to substituting environment variable:
#mykey = ${JAVA_HOME}

## Akka
# https://www.playframework.com/documentation/latest/ScalaAkka#Configuration
# https://www.playframework.com/documentation/latest/JavaAkka#Configuration
# ~~~~~
# Play uses Akka internally and exposes Akka Streams and actors in Websockets and
# other streaming HTTP responses.
akka {
  # "akka.log-config-on-start" is extraordinarly useful because it log the complete
  # configuration at INFO level, including defaults and overrides, so it s worth
  # putting at the very top.
  #
  # Put the following in your conf/logback.xml file:
  #
  # <logger name="akka.actor" level="INFO" />
  #
  # And then uncomment this line to debug the configuration.
  #
  #log-config-on-start = true
}

## Secret key
# https://www.playframework.com/documentation/latest/ApplicationSecret
# ~~~~~
# The secret key is used to sign Play's session cookie.
# This must be changed for production, but we don't recommend you change it in this file.
play.http.secret.key = ${?PLAY_SECRET}
pidfile.path = ${?PIDFILE_PATH}

## Modules
# https://www.playframework.com/documentation/latest/Modules
# ~~~~~
# Control which modules are loaded when Play starts.  Note that modules are
# the replacement for "GlobalSettings", which are deprecated in 2.5.x.
# Please see https://www.playframework.com/documentation/latest/GlobalSettings
# for more information.
#
# You can also extend Play functionality by using one of the publically available
# Play modules: https://playframework.com/documentation/latest/ModuleDirectory
play.modules {
  # By default, Play will load any class called Module that is defined
  # in the root package (the "app" directory), or you can define them
  # explicitly below.
  # If there are any built-in modules that you want to disable, you can list them here.
  #enabled += my.application.Module

  # If there are any built-in modules that you want to disable, you can list them here.
  #disabled += ""
}

## IDE
# https://www.playframework.com/documentation/latest/IDE
# ~~~~~
# Depending on your IDE, you can add a hyperlink for errors that will jump you
# directly to the code location in the IDE in dev mode. The following line makes
# use of the IntelliJ IDEA REST interface:
#play.editor="http://localhost:63342/api/file/?file=%s&line=%s"

## Internationalisation
# https://www.playframework.com/documentation/latest/JavaI18N
# https://www.playframework.com/documentation/latest/ScalaI18N
# ~~~~~
# Play comes with its own i18n settings, which allow the user's preferred language
# to map through to internal messages, or allow the language to be stored in a cookie.
play.i18n {
  # The application languages
  langs = [ "en" ]

  # Whether the language cookie should be secure or not
  #langCookieSecure = true

  # Whether the HTTP only attribute of the cookie should be set to true
  #langCookieHttpOnly = true
}

## Filters
# https://www.playframework.com/documentation/latest/ScalaHttpFilters
# https://www.playframework.com/documentation/latest/JavaHttpFilters
# ~~~~~
# Filters run code on every request. They can be used to perform
# common logic for all your actions, e.g. adding common headers.
#
play.filters {

  # Enabled filters are run automatically against Play.
  # CSRFFilter, AllowedHostFilters, and SecurityHeadersFilters are enabled by default.

  # Disabled filters remove elements from the enabled list.
  disabled += play.filters.hosts.AllowedHostsFilter
}

## Play HTTP settings
# ~~~~~
play.http {
  ## Router
  # https://www.playframework.com/documentation/latest/JavaRouting
  # https://www.playframework.com/documentation/latest/ScalaRouting
  # ~~~~~
  # Define the Router object to use for this application.
  # This router will be looked up first when the application is starting up,
  # so make sure this is the entry point.
  # Furthermore, it's assumed your route file is named properly.
  # So for an application router like `my.application.Router`,
  # you may need to define a router file `conf/my.application.routes`.
  # Default to Routes in the root package (aka "apps" folder) (and conf/routes)
  #router = my.application.Router

  ## Action Creator
  # https://www.playframework.com/documentation/latest/JavaActionCreator
  # ~~~~~
  #actionCreator = null

  ## ErrorHandler
  # https://www.playframework.com/documentation/latest/JavaRouting
  # https://www.playframework.com/documentation/latest/ScalaRouting
  # ~~~~~
  # If null, will attempt to load a class called ErrorHandler in the root package,
  #errorHandler = null

  ## Session & Flash
  # https://www.playframework.com/documentation/latest/JavaSessionFlash
  # https://www.playframework.com/documentation/latest/ScalaSessionFlash
  # ~~~~~
  session {
    # Sets the cookie to be sent only over HTTPS.
    #secure = true

    # Sets the cookie to be accessed only by the server.
    #httpOnly = true

    # Sets the max-age field of the cookie to 5 minutes.
    # NOTE: this only sets when the browser will discard the cookie. Play will consider any
    # cookie value with a valid signature to be a valid session forever. To implement a server side session timeout,
    # you need to put a timestamp in the session and check it at regular intervals to possibly expire it.
    #maxAge = 300

    # Sets the domain on the session cookie.
    #domain = "example.com"
  }

  flash {
    # Sets the cookie to be sent only over HTTPS.
    #secure = true

    # Sets the cookie to be accessed only by the server.
    #httpOnly = true
  }
}

## Netty Provider
# https://www.playframework.com/documentation/latest/SettingsNetty
# ~~~~~
play.server.netty {
  # Whether the Netty wire should be logged
  #log.wire = true

  # If you run Play on Linux, you can use Netty's native socket transport
  # for higher performance with less garbage.
  #transport = "native"
}

## WS (HTTP Client)
# https://www.playframework.com/documentation/latest/ScalaWS#Configuring-WS
# ~~~~~
# The HTTP client primarily used for REST APIs.  The default client can be
# configured directly, but you can also create different client instances
# with customized settings. You must enable this by adding to build.sbt:
#
# libraryDependencies += ws // or javaWs if using java
#
play.ws {
  # Sets HTTP requests not to follow 302 requests
  #followRedirects = false

  # Sets the maximum number of open HTTP connections for the client.
  #ahc.maxConnectionsTotal = 50

  ## WS SSL
  # https://www.playframework.com/documentation/latest/WsSSL
  # ~~~~~
  ssl {
    # Configuring HTTPS with Play WS does not require programming.  You can
    # set up both trustManager and keyManager for mutual authentication, and
    # turn on JSSE debugging in development with a reload.
    #debug.handshake = true
    #trustManager = {
    #  stores = [
    #    { type = "JKS", path = "exampletrust.jks" }
    #  ]
    #}
  }
}

## Cache
# https://www.playframework.com/documentation/latest/JavaCache
# https://www.playframework.com/documentation/latest/ScalaCache
# ~~~~~
# Play comes with an integrated cache API that can reduce the operational
# overhead of repeated requests. You must enable this by adding to build.sbt:
#
# libraryDependencies += cache
#
play.cache {
  # If you want to bind several caches, you can bind the individually
  #bindCaches = ["db-cache", "user-cache", "session-cache"]
}

## Filters
# https://www.playframework.com/documentation/latest/ScalaHttpFilters
# https://www.playframework.com/documentation/latest/JavaHttpFilters
# ~~~~~
# Filters run code on every request. They can be used to perform
# common logic for all your actions, e.g. adding common headers.
#

## Filter Configuration
# https://www.playframework.com/documentation/latest/Filters
# ~~~~~
# There are a number of built-in filters that can be enabled and configured
# to give Play greater security.
#
play.filters.disabled += play.filters.csrf.CSRFFilter
play.filters {
  ## CORS filter configuration
  # https://www.playframework.com/documentation/latest/CorsFilter
  # ~~~~~
  # CORS is a protocol that allows web applications to make requests from the browser
  # across different domains.
  # NOTE: You MUST apply the CORS configuration before the CSRF filter, as CSRF has
  # dependencies on CORS settings.
  cors {
    # Filter paths by a whitelist of path prefixes
    #pathPrefixes = ["/some/path", ...]

    # The allowed origins. If null, all origins are allowed.
    #allowedOrigins = ["https://www.example.com"]

    # The allowed HTTP methods. If null, all methods are allowed
    #allowedHttpMethods = ["GET", "POST"]
  }

  ## CSRF Filter
  # https://www.playframework.com/documentation/latest/ScalaCsrf#Applying-a-global-CSRF-filter
  # https://www.playframework.com/documentation/latest/JavaCsrf#Applying-a-global-CSRF-filter
  # ~~~~~
  # Play supports multiple methods for verifying that a request is not a CSRF request.
  # The primary mechanism is a CSRF token. This token gets placed either in the query string
  # or body of every form submitted, and also gets placed in the users session.
  # Play then verifies that both tokens are present and match.
  csrf {
    # Sets the cookie to be sent only over HTTPS
    #cookie.secure = true

    # Defaults to CSRFErrorHandler in the root package.
    #errorHandler = MyCSRFErrorHandler
  }

  ## Security headers filter configuration
  # https://www.playframework.com/documentation/latest/SecurityHeaders
  # ~~~~~
  # Defines security headers that prevent XSS attacks.
  # If enabled, then all options are set to the below configuration by default:
  headers {
    # The X-Frame-Options header. If null, the header is not set.
    #frameOptions = "DENY"

    # The X-XSS-Protection header. If null, the header is not set.
    #xssProtection = "1; mode=block"

    # The X-Content-Type-Options header. If null, the header is not set.
    #contentTypeOptions = "nosniff"

    # The X-Permitted-Cross-Domain-Policies header. If null, the header is not set.
    #permittedCrossDomainPolicies = "master-only"

    # The Content-Security-Policy header. If null, the header is not set.
    #contentSecurityPolicy = "default-src 'self'"
  }

  ## Allowed hosts filter configuration
  # https://www.playframework.com/documentation/latest/AllowedHostsFilter
  # ~~~~~
  # Play provides a filter that lets you configure which hosts can access your application.
  # This is useful to prevent cache poisoning attacks.
  hosts {
    # Allow requests to example.com, its subdomains, and localhost:9000.
    #allowed = [".example.com", "localhost:9000"]
  }
}
```

## Kong

The `Kong` gateway can be configured in 2 ways:

1. By letting the DS bootstrap the gateway using its default and configured values
2. By running a script

{% hint style="info" %}
The second option requires that the machine the script is executed on can access the admin API of the Kong Gateway.
{% endhint %}

### DS Bootstrapping

Using a valid token obtained from Keycloak, execute the following request:

```javascript
curl --location --request POST 'http://localhost:4600/v3/gateway/bootstrap' \
--header 'Authorization: Bearer eyJ...MZA' \
--header 'Content-Type: application/json' \
--data-raw '{
    "dsServiceName": "t1c-ds-v3",
    "dsServiceHost": "t1c-ds",
    "dsPort": 9000
}'
```

| Property      | Description                                                                    |
| ------------- | ------------------------------------------------------------------------------ |
| dsServiceName | The name of the DS API service to create on the gateway. Can be freely chosen. |
| dsServiceHost | The hostname of the DS API service                                             |
| dsPort        | The port to which the gateway can proxy requests                               |

### Script

You can also run a script to configure the `Kong` gateway. However, you need to adjust the script to your needs prior to executing it. You **must** also run it on  a device on which `curl` is available.

```javascript
# Adjust the service host and port to the correct values, as well as the gateway admin URL

# Create service
curl \
  --verbose \
  --request PUT \
  --header 'Content-Type: application/json' \
  --data '{"name":"t1c-ds-v3","host":"t1c-ds","port":9000}' \
  'http://localhost:8001/services/t1c-ds-v3'
# Create JWT Auth route
curl \
  --verbose \
  --request PUT \
  --header 'Content-Type: application/json' \
  --data '{"name":"jwt-route","strip_path":false,"paths":["/v3/configurations/","/v3/configurations","/v3/devices/","/v3/devices","/v3/gateway/","/v3/labels/","/v3/labels","/v3/organizations/","/v3/organizations","/v3/registration/","/v3/versions/","/v3/versions","/v3/transactions/"]}' \
  'http://localhost:8001/services/t1c-ds-v3/routes/jwt-route'
# Create Key Auth route
curl \
  --verbose \
  --request PUT \
  --header 'Content-Type: application/json' \
  --data '{"name":"key-auth-route","strip_path":false,"paths":["/v3/tokens/"]}' \
  'http://localhost:8001/services/t1c-ds-v3/routes/key-auth-route'
# Create No-Auth route
curl \
  --verbose \
  --request PUT \
  --header 'Content-Type: application/json' \
  --data '{"name":"no-auth-route","strip_path":false,"paths":["/v3/system/","/v3/device/","/v3/downloads/","/rmc/","/rmc","/mgt/","/mgt","/"]}' \
  'http://localhost:8001/services/t1c-ds-v3/routes/no-auth-route'
# Create JWT route plugin
curl \
  --verbose \
  --request POST \
  --header 'Content-Type: application/json' \
  --data '{"name":"jwt","route":{"name":"jwt-route"},"config":{"run_on_preflight":false,"claims_to_verify":["exp"]}}' \
  'http://localhost:8001/routes/jwt-route/plugins'
# Create Key-Auth route plugin
curl \
  --verbose \
  --request POST \
  --header 'Content-Type: application/json' \
  --data '{"name":"key-auth","route":{"name":"key-auth-route"},"config":{"run_on_preflight":false}}' \
  'http://localhost:8001/routes/key-auth-route/plugins'
# Create User consumer
curl \
  --verbose \
  --request PUT \
  --header 'Content-Type: application/json' \
  --data '{"username":"t1cds-user","custom_id":"t1cds-user"}' \
  'http://localhost:8001/consumers/t1cds-user'
# Create Registration consumer
curl \
  --verbose \
  --request PUT \
  --header 'Content-Type: application/json' \
  --data '{"username":"t1cds-reg","custom_id":"t1cds-reg"}' \
  'http://localhost:8001/consumers/t1cds-reg'
# Create Application consumer
curl \
  --verbose \
  --request PUT \
  --header 'Content-Type: application/json' \
  --data '{"username":"t1cds-app","custom_id":"t1cds-app"}' \
  'http://localhost:8001/consumers/t1cds-app'
# Create Registration consumer JWT plugin. Replace the rsa_public_key by the PEM encoded DS public key
curl \
  --verbose \
  --request POST \
  --header 'Content-Type: application/json' \
  --data '{"key":"t1cds-reg","algorithm":"RS256","rsa_public_key":"-----BEGIN PUBLIC KEY-----\n ... [[PEM PUBLIC KEY]] ... \n-----END PUBLIC KEY-----\n"}' \
  'http://localhost:8001/consumers/t1cds-reg/jwt'
# Create Application consumer JWT plugin. Replace the rsa_public_key by the PEM encoded DS public key
curl \
  --verbose \
  --request POST \
  --header 'Content-Type: application/json' \
  --data '{"key":"t1cds-app","algorithm":"RS256","rsa_public_key":"-----BEGIN PUBLIC KEY-----\n ... [[PEM PUBLIC KEY]] ... \n-----END PUBLIC KEY-----\n"}' \
  'http://localhost:8001/consumers/t1cds-app/jwt'
# Create User consumer JWT plugin. Replace the rsa_public_key by the PEM encoded DS public key
curl \
  --verbose \
  --request POST \
  --header 'Content-Type: application/json' \
  --data '{"key":"http://localhost:9999/auth/realms/trust1connector","algorithm":"RS256","rsa_public_key":"-----BEGIN PUBLIC KEY-----\n ... [[PEM PUBLIC KEY]] ... \n-----END PUBLIC KEY-----\n"}' \
  'http://localhost:8001/consumers/t1cds-user/jwt'
```

The script contains requests to create every required entity on the `Kong` gateway. An overview can be found in the table below:

| Entity Name    | Entity Type | Enabled Plugins                                                                 | Paths                                                                                                                                                                                                                                         |
| -------------- | ----------- | ------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| t1c-ds-v3      | Service     |                                                                                 |                                                                                                                                                                                                                                               |
| jwt-route      | Route       | `jwt`                                                                           | "/v3/configurations/", "/v3/configurations", "/v3/devices/", "/v3/devices", "/v3/gateway/", "/v3/labels/", "/v3/labels", "/v3/organizations/", "/v3/organizations", "/v3/registration/", "/v3/versions/", "/v3/versions", "/v3/transactions/" |
| key-auth-route | Route       | `key-auth`                                                                      | "/v3/tokens/"                                                                                                                                                                                                                                 |
| no-auth-route  | Route       |                                                                                 | "/v3/system/", "/v3/device/", "/v3/downloads/", "/rmc/", "/rmc", "/mgt/", "/mgt", "/"                                                                                                                                                         |
| t1cds-reg      | Consumer    | `jwt` (`key-auth` plugin will be dynamically added when creating a new version) |                                                                                                                                                                                                                                               |
| t1cds-app      | Consumer    | `jwt` (`key-auth` plugin will be dynamically added when creating a new label)   |                                                                                                                                                                                                                                               |
| t1cds-user     | Consumer    | `jwt`                                                                           |                                                                                                                                                                                                                                               |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://t1t.gitbook.io/t1c-distribution-service-v3-guide/3.0.8/configuration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
