Repository: avenga/couper
Pull request #485 (2022-04-13 16:02:56)

added disable_access_control attribute to block documentation
* added `disable_access_control` attribute to block documentation
* clarified type for several attributes and variables
* fixed default value for `hosts`

---
<details>
    <summary>Reviewer checklist</summary>
    <ul>
        <li>Read PR description: a summary about the changes is required</li>
        <li>Changelog updated</li>
        <li>Documentation: docs/{Reference, Cli, ...}, Docker and cli help/usage</li>
        <li>Pulled branch, manually tested</li>
        <li>Verified requirements are met</li>
        <li>Reviewed the code</li>
        <li>Reviewed the related tests</li>
    </ul>
</details>



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3f412de7..efc6106e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,7 @@ Unreleased changes are available as `avenga/couper:edge` container.
     * removed `beta_operation_denied` and `beta_scope` [error types](./docs/ERRORS.md#api-and-endpoint-error-types)
     * renamed `beta_insufficient_scope` [error type](./docs/ERRORS.md#api-and-endpoint-error-types) to `beta_insufficient_permissions`
     * added `request.context.beta_required_permission` and `request.context.beta_granted_permissions` [request variables](./docs/REFERENCE.md#request)
+  * Clarified the type of various [attributes/variables](./docs/REFERENCE.md) ([#485](https://github.com/avenga/couper/pull/485))
 
 * **Fixed**
   * Keys in object type attribute values are only handled case-insensitively if reasonable (e.g. they represent HTTP methods or header field values) ([#461](https://github.com/avenga/couper/pull/461))
diff --git a/docs/REFERENCE.md b/docs/REFERENCE.md
index 93b25633..34721002 100644
--- a/docs/REFERENCE.md
+++ b/docs/REFERENCE.md
@@ -63,10 +63,11 @@ The `server` block is one of the root configuration blocks of Couper's configura
 | Attribute(s)     | Type   | Default      | Description | Characteristic(s) | Example |
 | :--------------- | :----- | :----------- | :---------- | :---------------- | :------ |
 | `base_path`      | string | -            | Configures the path prefix for all requests. | &#9888; Inherited by nested blocks. | `base_path = "/api"` |
-| `hosts`          | list   | port `:8080` | - | &#9888; required, if there is more than one `server` block. &#9888; Only one `hosts` attribute per `server` block is allowed. | `hosts = ["example.com", "localhost:9090"]` |
+| `hosts`          | tuple (string) | `["*:8080"]` | - | &#9888; required, if there is more than one `server` block. &#9888; Only one `hosts` attribute per `server` block is allowed. | `hosts = ["example.com", "localhost:9090"]` |
 | `error_file`     | string | -            | Location of the error file template. | - | `error_file = "./my_error_page.html"` |
-| `access_control` | list   | -            | Sets predefined [Access Control](#access-control) for `server` block context. | &#9888; Inherited by nested blocks. | `access_control = ["foo"]` |
-| `custom_log_fields` | map | -            | Defines log fields for [Custom Logging](LOGS.md#custom-logging). | &#9888; Inherited by nested blocks. | - |
+| `access_control` | tuple (string) | -    | Sets predefined [Access Control](#access-control) for `server` block context. | &#9888; Inherited by nested blocks. | `access_control = ["foo"]` |
+| `disable_access_control` | tuple (string) | - | Disables access controls by name. | - | `disable_access_control = ["foo"]` |
+| `custom_log_fields` | object | -         | Defines log fields for [Custom Logging](LOGS.md#custom-logging). | &#9888; Inherited by nested blocks. | - |
 
 ### Files Block
 
@@ -81,8 +82,9 @@ The `files` block configures the file serving.
 | `base_path`      | string | -       | Configures the path prefix for all requests. | - | `base_path = "/files"` |
 | `document_root`  | string | -       | Location of the document root. | &#9888; required | `document_root = "./htdocs"` |
 | `error_file`     | string | -       | Location of the error file template. | - | - |
-| `access_control` | list   | -       | Sets predefined [Access Control](#access-control) for `files` block context. | - | `access_control = ["foo"]` |
-| `custom_log_fields` | map | -       | Defines log fields for [Custom Logging](LOGS.md#custom-logging). | &#9888; Inherited by nested blocks. | - |
+| `access_control` | tuple (string) | - | Sets predefined [Access Control](#access-control) for `files` block context. | - | `access_control = ["foo"]` |
+| `disable_access_control` | tuple (string) | - | Disables access controls by name. | - | `disable_access_control = ["foo"]` |
+| `custom_log_fields` | object | -    | Defines log fields for [Custom Logging](LOGS.md#custom-logging). | &#9888; Inherited by nested blocks. | - |
 
 ### SPA Block
 
@@ -96,9 +98,10 @@ The `spa` block configures the Web serving for SPA assets.
 | :--------------- | :----- | :------ | :---------- | :---------------- | :------ |
 | `base_path`      | string | -       | Configures the path prefix for all requests. | - | `base_path = "/assets"` |
 | `bootstrap_file` | string | -       | Location of the bootstrap file. | &#9888; required | `bootstrap_file = "./htdocs/index.html"` |
-| `paths`          | list   | -       | List of SPA paths that need the bootstrap file. | &#9888; required | `paths = ["/app/**"]` |
-| `access_control` | list   | -       | Sets predefined [Access Control](#access-control) for `spa` block context. | - | `access_control = ["foo"]` |
-| `custom_log_fields` | map | -       | Defines log fields for [Custom Logging](LOGS.md#custom-logging). | &#9888; Inherited by nested blocks. | - |
+| `paths`          | tuple (string) | - | List of SPA paths that need the bootstrap file. | &#9888; required | `paths = ["/app/**"]` |
+| `access_control` | tuple (string) | - | Sets predefined [Access Control](#access-control) for `spa` block context. | - | `access_control = ["foo"]` |
+| `disable_access_control` | tuple (string) | - | Disables access controls by name. | - | `disable_access_control = ["foo"]` |
+| `custom_log_fields` | object | -    | Defines log fields for [Custom Logging](LOGS.md#custom-logging). | &#9888; Inherited by nested blocks. | - |
 
 ### API Block
 
@@ -115,10 +118,11 @@ as json error with an error body payload. This can be customized via `error_file
 | :------------------------------  | :--------------- | :--------------- | :--------------- | :--------------- | :--------------- |
 |`base_path`|string|-|Configures the path prefix for all requests.|| `base_path = "/v1"`|
 | `error_file` |string|-|Location of the error file template.|-|`error_file = "./my_error_body.json"`|
-| `access_control` |list|-|Sets predefined [Access Control](#access-control) for `api` block context.|&#9888; Inherited by nested blocks.| `access_control = ["foo"]`|
-| `allowed_methods` | tuple of string | `["*"]` == `["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"]` | Sets allowed methods as _default_ for all contained endpoints. Requests with a method that is not allowed result in an error response with a `405 Method Not Allowed` status. | The default value `*` can be combined with additional methods. Methods are matched case-insensitively. `Access-Control-Allow-Methods` is only sent in response to a [CORS](#cors-block) preflight request, if the method requested by `Access-Control-Request-Method` is an allowed method. | `allowed_methods = ["GET", "POST"]` or `allowed_methods = ["*", "BREW"]` |
-| `beta_required_permission` |string or object|-|Permission required to use this API (see [error type](ERRORS.md#error-types) `beta_insufficient_permissions`).|If the value is a string, the same permission applies to all request methods. If there are different permissions for different request methods, use an object with the request methods as keys and string values. Methods not specified in this object are not permitted. `"*"` is the key for "all other standard methods". Methods other than `GET`, `HEAD`, `POST`, `PUT`, `PATCH`, `DELETE`, `OPTIONS` must be specified explicitly. A value `""` means "no permission required".| `beta_required_permission = "read"` or `beta_required_permission = { post = "write", "*" = "" }`|
-| `custom_log_fields` | map | - | Defines log fields for [Custom Logging](LOGS.md#custom-logging). | &#9888; Inherited by nested blocks. | - |
+| `access_control` |tuple (string)|-|Sets predefined [Access Control](#access-control) for `api` block context.|&#9888; Inherited by nested blocks.| `access_control = ["foo"]`|
+| `disable_access_control` | tuple (string) | - | Disables access controls by name. | - | `disable_access_control = ["foo"]` |
+| `allowed_methods` | tuple (string) | `["*"]` == `["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"]` | Sets allowed methods as _default_ for all contained endpoints. Requests with a method that is not allowed result in an error response with a `405 Method Not Allowed` status. | The default value `*` can be combined with additional methods. Methods are matched case-insensitively. `Access-Control-Allow-Methods` is only sent in response to a [CORS](#cors-block) preflight request, if the method requested by `Access-Control-Request-Method` is an allowed method. | `allowed_methods = ["GET", "POST"]` or `allowed_methods = ["*", "BREW"]` |
+| `beta_required_permission` |string or object (string)|-|Permission required to use this API (see [error type](ERRORS.md#error-types) `beta_insufficient_permissions`).|If the value is a string, the same permission applies to all request methods. If there are different permissions for different request methods, use an object with the request methods as keys and string values. Methods not specified in this object are not permitted. `"*"` is the key for "all other standard methods". Methods other than `GET`, `HEAD`, `POST`, `PUT`, `PATCH`, `DELETE`, `OPTIONS` must be specified explicitly. A value `""` means "no permission required".| `beta_required_permission = "read"` or `beta_required_permission = { post = "write", "*" = "" }`|
+| `custom_log_fields` | object | - | Defines log fields for [Custom Logging](LOGS.md#custom-logging). | &#9888; Inherited by nested blocks. | - |
 
 ### Endpoint Block
 
@@ -138,10 +142,11 @@ produce an explicit or implicit client response.
 |:------------------------|:-----------------|:--------|:------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------|
 | `request_body_limit`    | string           | `64MiB` | Configures the maximum buffer size while accessing `request.form_body` or `request.json_body` content.            | &#9888; Valid units are: `KiB, MiB, GiB`                                                                                                                                                                                                                                                                                                                                                                                                        | `request_body_limit = "200KiB"`                                      |
 | `path`                  | string           | -       | Changeable part of the upstream URL. Changes the path suffix of the outgoing request.                             | -                                                                                                                                                                                                                                                                                                                                                                                                                                               | -                                                                    |
-| `access_control`        | list             | -       | Sets predefined [Access Control](#access-control) for `endpoint` block context.                                   | -                                                                                                                                                                                                                                                                                                                                                                                                                                               | `access_control = ["foo"]`                                           |
-| `allowed_methods`       | tuple of string  | `["*"]` == `["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"]` | Sets allowed methods _overriding_ a default set in the containing `api` block. Requests with a method that is not allowed result in an error response with a `405 Method Not Allowed` status. | The default value `*` can be combined with additional methods. Methods are matched case-insensitively. `Access-Control-Allow-Methods` is only sent in response to a [CORS](#cors-block) preflight request, if the method requested by `Access-Control-Request-Method` is an allowed method. | `allowed_methods = ["GET", "POST"]` or `allowed_methods = ["*", "BREW"]` |
-| `beta_required_permission` | string or object | -    | Permission required to use this endpoint (see [error type](ERRORS.md#error-types) `beta_insufficient_permissions`).| Overrides `beta_required_permission` in a containing `api` block. If the value is a string, the same permission applies to all request methods. If there are different permissions for different request methods, use an object with the request methods as keys and string values. Methods not specified in this object are not permitted. `"*"` is the key for "all other standard methods". Methods other than `GET`, `HEAD`, `POST`, `PUT`, `PATCH`, `DELETE`, `OPTIONS` must be specified explicitly. A value `""` means "no permission required". For `api` blocks with at least two `endpoint`s, all endpoints must have either a) no `beta_required_permission` set or b) either `beta_required_permission` or `disable_access_control` set. Otherwise, a configuration error is thrown. | `beta_required_permission = "read"` or `beta_required_permission = { post = "write", "*" = "" }` |
-| `custom_log_fields`     | map              | -       | Defines log fields for [Custom Logging](LOGS.md#custom-logging).                                                  | &#9888; Inherited by nested blocks.                                                                                                                                                                                                                                                                                                                                                                                                             | -                                                                    |
+| `access_control`        | tuple (string)   | -       | Sets predefined [Access Control](#access-control) for `endpoint` block context.                                   | -                                                                                                                                                                                                                                                                                                                                                                                                                                               | `access_control = ["foo"]`                                           |
+| `disable_access_control` | tuple (string)  | -       | Disables access controls by name.                                                                                 | -                                                                                                                                                                                                                                                                                                                                                                                                                                               | `disable_access_control = ["foo"]`                                   |
+| `allowed_methods`       | tuple (string)  | `["*"]` == `["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"]` | Sets allowed methods _overriding_ a default set in the containing `api` block. Requests with a method that is not allowed result in an error response with a `405 Method Not Allowed` status. | The default value `*` can be combined with additional methods. Methods are matched case-insensitively. `Access-Control-Allow-Methods` is only sent in response to a [CORS](#cors-block) preflight request, if the method requested by `Access-Control-Request-Method` is an allowed method. | `allowed_methods = ["GET", "POST"]` or `allowed_methods = ["*", "BREW"]` |
+| `beta_required_permission` | string or object (string) | -    | Permission required to use this endpoint (see [error type](ERRORS.md#error-types) `beta_insufficient_permissions`).| Overrides `beta_required_permission` in a containing `api` block. If the value is a string, the same permission applies to all request methods. If there are different permissions for different request methods, use an object with the request methods as keys and string values. Methods not specified in this object are not permitted. `"*"` is the key for "all other standard methods". Methods other than `GET`, `HEAD`, `POST`, `PUT`, `PATCH`, `DELETE`, `OPTIONS` must be specified explicitly. A value `""` means "no permission required". For `api` blocks with at least two `endpoint`s, all endpoints must have either a) no `beta_required_permission` set or b) either `beta_required_permission` or `disable_access_control` set. Otherwise, a configuration error is thrown. | `beta_required_permission = "read"` or `beta_required_permission = { post = "write", "*" = "" }` |
+| `custom_log_fields`     | object           | -       | Defines log fields for [Custom Logging](LOGS.md#custom-logging).                                                  | &#9888; Inherited by nested blocks.                                                                                                                                                                                                                                                                                                                                                                                                             | -                                                                    |
 | [Modifiers](#modifiers) | -                | -       | -                                                                                                                 | -                                                                                                                                                                                                                                                                                                                                                                                                                                               | -                                                                    |
 
 #### Endpoint Sequence
@@ -163,7 +168,7 @@ The `proxy` block creates and executes a proxy request to a backend service.
 | Attribute(s)            | Type           | Default | Description                                                                                                                                                                                                                                                      | Characteristic(s)                                                                      | Example             |
 |:------------------------|:---------------|:--------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------|:--------------------|
 | `backend`               | string         | -       | [Backend Block](#backend-block) reference, defined in [Definitions Block](#definitions-block)                                                                                                                                                                    | &#9888; required, if no [Backend Block](#backend-block) or `url` attribute is defined. | `backend = "foo"`   |
-| `expected_status`       | list of number | -       | If defined, the response status code will be verified against this list of codes. If the status-code is unexpected an [`unexpected_status` error](ERRORS.md#error-types) can be handled with an [`error_handler`](ERRORS.md#endpoint-related-error_handler). | -                                                                                      | -                   |
+| `expected_status`       | tuple (number) | -       | If defined, the response status code will be verified against this list of codes. If the status-code is unexpected an [`unexpected_status` error](ERRORS.md#error-types) can be handled with an [`error_handler`](ERRORS.md#endpoint-related-error_handler). | -                                                                                      | -                   |
 | `url`                   | string         | -       | If defined, the host part of the URL must be the same as the `origin` attribute of the [Backend Block](#backend-block) (if defined).                                                                                                                             | -                                                                                      | -                   |
 | `websockets`            | bool           | false   | Allows support for websockets. This attribute is only allowed in the 'default' `proxy` block. Other `proxy` blocks, [Request Blocks](#request-block) or [Response Blocks](#response-block) are not allowed in the current [Endpoint Block](#endpoint-block).     | &#9888; Either websockets attribute or block is allowed.                               | `websockets = true` |
 | [Modifiers](#modifiers) | -              | -       | -                                                                                                                                                                                                                                                                | -                                                                                      | -                   |
@@ -183,10 +188,10 @@ The `request` block creates and executes a request to a backend service.
 |:------------------|:--------------------------------------|:--------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------|
 | `backend`         | string                                | -       | `backend` block reference, defined in [Definitions Block](#definitions-block)                                                                                                                                                                                                                    | &#9888; required, if no [Backend Block](#backend-block) is defined.                                                                                                                    | `backend = "foo"` |
 | `body`            | string                                | -       | -                                                                                                                                                                                                                                                                                                | Creates implicit default `Content-Type: text/plain` header field.                                                                                                                      | -                 |
-| `expected_status` | list of number                        | -       | If defined, the response status code will be verified against this list of codes. If the status-code is unexpected an [`unexpected_status` error](ERRORS.md#error-types) can be handled with an [`error_handler`](ERRORS.md#endpoint-related-error_handler).                                 | -                                                                                                                                                                                      | -                 |
-| `form_body`       | map                                   | -       | -                                                                                                                                                                                                                                                                                                | Creates implicit default `Content-Type: application/x-www-form-urlencoded` header field.                                                                                               | -                 |
-| `headers`         | map                                   | -       | -                                                                                                                                                                                                                                                                                                | Same as `set_request_headers` in [Request Header](#request-header).                                                                                                                    | -                 |
-| `json_body`       | null, bool, number, string, map, list | -       | -                                                                                                                                                                                                                                                                                                | Creates implicit default `Content-Type: text/plain` header field.                                                                                                                      | -                 |
+| `expected_status` | tuple (number)                        | -       | If defined, the response status code will be verified against this list of codes. If the status-code is unexpected an [`unexpected_status` error](ERRORS.md#error-types) can be handled with an [`error_handler`](ERRORS.md#endpoint-related-error_handler).                                 | -                                                                                                                                                                                      | -                 |
+| `form_body`       | object                                | -       | -                                                                                                                                                                                                                                                                                                | Creates implicit default `Content-Type: application/x-www-form-urlencoded` header field.                                                                                               | -                 |
+| `headers`         | object                                | -       | -                                                                                                                                                                                                                                                                                                | Same as `set_request_headers` in [Request Header](#request-header).                                                                                                                    | -                 |
+| `json_body`       | null, bool, number, string, object, tuple | -   | -                                                                                                                                                                                                                                                                                                | Creates implicit default `Content-Type: text/plain` header field.                                                                                                                      | -                 |
 | `method`          | string                                | `GET`   | -                                                                                                                                                                                                                                                                                                | -                                                                                                                                                                                      | -                 |
 | `query_params`    | -                                     | -       | -                                                                                                                                                                                                                                                                                                | Same as `set_query_params` in [Query Parameter](#query-parameter).                                                                                                                     | -                 |
 | `url`             | string                                | -       | -                                                                                                                                                                                                                                                                                                | If defined, the host part of the URL must be the same as the `origin` attribute of the used [Backend Block](#backend-block) or [Backend Block Reference](#backend-block) (if defined). | -                 |
@@ -202,9 +207,9 @@ The `response` block creates and sends a client response.
 | Attribute(s) | Type |Default|Description|Characteristic(s)| Example|
 | :------------------------------ | :--------------- | :--------------- | :--------------- | :--------------- | :--------------- |
 | `body`         | string|-|-|Creates implicit default `Content-Type: text/plain` header field.|-|
-| `json_body`    | null, bool, number, string, map, list|-|-|Creates implicit default `Content-Type: application/json` header field.|-|
+| `json_body`    | null, bool, number, string, object, tuple|-|-|Creates implicit default `Content-Type: application/json` header field.|-|
 | `status`       | integer|`200`|HTTP status code.|-|-|
-| `headers`      |map|-|Same as `set_response_headers` in [Request Header](#response-header).                  |-|-|
+| `headers`      |object|-|Same as `set_response_headers` in [Request Header](#response-header).                  |-|-|
 
 ### Backend Block
 
@@ -219,7 +224,7 @@ The `backend` block defines the connection to a local/remote backend service.
 | Attribute(s) | Type |Default|Description|Characteristic(s)| Example|
 | :------------------------------ | :--------------- | :--------------- | :--------------- | :--------------- | :--------------- |
 | `basic_auth`                    | string|-|Basic auth for the upstream request. | format is `username:password`|-|
-| `custom_log_fields`             | map                 | -             | Defines log fields for [Custom Logging](LOGS.md#custom-logging). | - | - |
+| `custom_log_fields`             | object           | -                | Defines log fields for [Custom Logging](LOGS.md#custom-logging). | - | - |
 | `hostname`                      | string |-|Value of the HTTP host header field for the origin request. |Since `hostname` replaces the request host the value will also be used for a server identity check during a TLS handshake with the origin.|-|
 | `origin`                        |string|-|URL to connect to for backend requests.|&#9888; required.  &#9888; Must start with the scheme `http://...`.|-|
 | `path`                          | string|-|Changeable part of upstream URL.|-|-|
@@ -281,7 +286,7 @@ The `cors` block configures the CORS (Cross-Origin Resource Sharing) behavior in
 
 | Attribute(s) | Type |Default|Description|Characteristic(s)| Example|
 | :------------------------------ | :--------------- | :--------------- | :--------------- | :--------------- | :--------------- |
-| `allowed_origins`   | list|-|A list of allowed origin(s).|Can be either of: a string with a single specific origin, `"*"` (all origins are allowed) or an array of specific origins | `allowed_origins = ["https://www.example.com", "https://www.another.host.org"]`|
+| `allowed_origins`   | string or tuple (string) |-| An allowed origin or a list of allowed origins.|Can be either of: a string with a single specific origin, `"*"` (all origins are allowed) or an array of specific origins | `allowed_origins = ["https://www.example.com", "https://www.another.host.org"]`|
 | `allow_credentials` |bool|`false`| Set to `true` if the response can be shared with credentialed requests (containing `Cookie` or `Authorization` HTTP header fields).|-|-|
 | `disable`           | bool|`false`|Set to `true` to disable the inheritance of CORS from the [Server Block](#server-block) in [Files Block](#files-block), [SPA Block](#spa-block) and [API Block](#api-block) contexts.|-|-|
 | `max_age`           |[duration](#duration)|-|Indicates the time the information provided by the `Access-Control-Allow-Methods` and `Access-Control-Allow-Headers` response HTTP header fields.|&#9888; Can be cached|`max_age = "1h"`|
@@ -306,7 +311,7 @@ The `oauth2` block in the [Backend Block](#backend-block) context configures the
 | `client_secret` |string|-|The client password.|&#9888; required.|-|
 | `retries` |integer|`1` | The number of retries to get the token and resource, if the resource-request responds with `401 Unauthorized` HTTP status code.|-|-|
 | `token_endpoint_auth_method` |string|`client_secret_basic`|Defines the method to authenticate the client at the token endpoint.|If set to `client_secret_post`, the client credentials are transported in the request body. If set to `client_secret_basic`, the client credentials are transported via Basic Authentication.|-|
-| `scope`                      |string|-|  A space separated list of requested scope values for the access token.|-| `scope = "read write"` |
+| `scope`                      |string|-| A space separated list of requested scope values for the access token.|-| `scope = "read write"` |
 
 The HTTP header field `Accept: application/json` is automatically added to the token request. This can be modified with [request header modifiers](#request-header) in a [backend block](#backend-block).
 
@@ -357,7 +362,7 @@ by `htpasswd_file` otherwise.
 | `password`      | string | `""`    | The corresponding password. | - | - |
 | `htpasswd_file` | string | `""`    | The htpasswd file. | Couper uses [Apache's httpasswd](https://httpd.apache.org/docs/current/programs/htpasswd.html) file format. `apr1`, `md5` and `bcrypt` password encryptions are supported. The file is loaded once at startup. Restart Couper after you have changed it. | - |
 | `realm`         | string | `""`    | The realm to be sent in a `WWW-Authenticate` response HTTP header field. | - | - |
-| `custom_log_fields` | map | - | Defines log fields for [Custom Logging](LOGS.md#custom-logging). | &#9888; Inherited by nested blocks. | - |
+| `custom_log_fields` | object | -   | Defines log fields for [Custom Logging](LOGS.md#custom-logging). | &#9888; Inherited by nested blocks. | - |
 
 The `user` is accessable via `request.context.<label>.user` for successfully authenticated requests.
 
@@ -377,7 +382,7 @@ Since responses from endpoints protected by JWT access controls are not publicly
 | Attribute(s) | Type |Default|Description|Characteristic(s)| Example|
 | :-------- | :--------------- | :--------------- | :--------------- | :--------------- | :--------------- |
 | `cookie`  |string|-|Read token value from a cookie.|cannot be used together with `header` or `token_value` |`cookie = "AccessToken"`|
-| `custom_log_fields` | map | - | Defines log fields for [Custom Logging](LOGS.md#custom-logging). | &#9888; Inherited by nested blocks. | - |
+| `custom_log_fields` | object | - | Defines log fields for [Custom Logging](LOGS.md#custom-logging). | &#9888; Inherited by nested blocks. | - |
 | `header`          |string|-|Read token value from a request header field.|&#9888; Implies `Bearer` if `Authorization` (case-insensitive) is used, otherwise any other header name can be used. Cannot be used together with `cookie` or `token_value`.|`header = "Authorization"` |
 | `token_value` | string | - | expression to obtain the token | cannot be used together with `cookie` or `header` | `token_value = request.form_body.token[0]`|
 | `key`           |string|-|Public key (in PEM format) for `RS*` and `ES*` variants or the secret for `HS*` algorithm.|-|-|
@@ -386,9 +391,9 @@ Since responses from endpoints protected by JWT access controls are not publicly
 | `claims`               |object|-|Object with claims that must be given for a valid token (equals comparison with JWT payload).| The claim values are evaluated per request. | `claims = { pid = request.path_params.pid }` |
 | `required_claims`      |string|-|List of claim names that must be given for a valid token |-|`required_claims = ["roles"]`|
 | `beta_permissions_claim` |string|-|name of claim containing the granted permissions|The claim value must either be a string containing a space-separated list of permissions or a list of string permissions|`beta_permissions_claim = "scope"`|
-| `beta_permissions_map` |map|-| mapping of granted permissions to additional granted permissions | Maps values from `beta_permissions_claim` and those created from `beta_roles_map`. The map is called recursively. |`beta_permissions_map = { p1 = ["p3", "p4"], p2 = ["p5"] }`|
+| `beta_permissions_map` |object (string)|-| mapping of granted permissions to additional granted permissions | Maps values from `beta_permissions_claim` and those created from `beta_roles_map`. The map is called recursively. |`beta_permissions_map = { p1 = ["p3", "p4"], p2 = ["p5"] }`|
 | `beta_roles_claim` |string|-|name of claim specifying the roles of the user represented by the token|The claim value must either be a string containing a space-separated list of role values or a list of string role values|`beta_roles_claim = "roles"`|
-| `beta_roles_map` |map|-| mapping of roles to granted permissions | Non-mapped roles can be assigned with `*` to specific permissions. |`beta_roles_map = { role1 = ["p1", "p2"], role2 = ["p3"], "*" = ["public"] }`|
+| `beta_roles_map` |object (string)|-| mapping of roles to granted permissions | Non-mapped roles can be assigned with `*` to specific permissions. |`beta_roles_map = { role1 = ["p1", "p2"], role2 = ["p3"], "*" = ["public"] }`|
 | `jwks_url` | string | - | URI pointing to a set of [JSON Web Keys (RFC 7517)](https://datatracker.ietf.org/doc/html/rfc7517) | - | `jwks_url = "http://identityprovider:8080/jwks.json"` |
 | `jwks_ttl` | [duration](#duration) | `"1h"` | Time period the JWK set stays valid and may be cached. | - | `jwks_ttl = "1800s"` |
 | `backend`  | string| - | [backend reference](#backend-block) for enhancing JWKS requests| - | `backend = "jwks_backend"` |
@@ -461,7 +466,7 @@ Like all [Access Control](#access-control) types, the `beta_oauth2` block is def
 | `scope` |string|-| A space separated list of requested scope values for the access token.| - | `scope = "read write"` |
 | `verifier_method` | string | - | The method to verify the integrity of the authorization code flow | &#9888; required, available values: `ccm_s256` (`code_challenge` parameter with `code_challenge_method` `S256`), `state` (`state` parameter) | `verifier_method = "ccm_s256"` |
 | `verifier_value` | string or expression | - | The value of the (unhashed) verifier. | &#9888; required; e.g. using cookie value created with [`oauth2_verifier()` function](#functions) | `verifier_value = request.cookies.verifier` |
-| `custom_log_fields` | map | - | Defines log fields for [Custom Logging](LOGS.md#custom-logging). | &#9888; Inherited by nested blocks. | - |
+| `custom_log_fields` | object | - | Defines log fields for [Custom Logging](LOGS.md#custom-logging). | &#9888; Inherited by nested blocks. | - |
 
 If the authorization server supports the `code_challenge_method` `S256` (a.k.a. PKCE, see RFC 7636), we recommend `verifier_method = "ccm_s256"`.
 
@@ -490,7 +495,7 @@ Like all [Access Control](#access-control) types, the `oidc` block is defined in
 | `scope`                      | string                | -                     | A space separated list of requested scope values for the access token.               | `openid` is automatically added.                                                                                                                                                                                            | `scope = "profile read"`                    |
 | `verifier_method`            | string                | -                     | The method to verify the integrity of the authorization code flow              | available values: `ccm_s256` (`code_challenge` parameter with `code_challenge_method` `S256`), `nonce` (`nonce` parameter)                                                                                                        | `verifier_method = "nonce"`                 |
 | `verifier_value`             | string or expression  | -                     | The value of the (unhashed) verifier.                                          | &#9888; required; e.g. using cookie value created with [`oauth2_verifier()` function](#functions)                                                                                                                                 | `verifier_value = request.cookies.verifier` |
-| `custom_log_fields`          | map                   | -                     | Defines log fields for [Custom Logging](LOGS.md#custom-logging).               | &#9888; Inherited by nested blocks.                                                                                                                                                                                               | -                                           |
+| `custom_log_fields`          | object                | -                     | Defines log fields for [Custom Logging](LOGS.md#custom-logging).               | &#9888; Inherited by nested blocks.                                                                                                                                                                                               | -                                           |
 | `configuration_backend`      | string                | -                     | [Backend Block Reference](#backend-block)                                      | &#9888; Do not disable the peer certificate validation with `disable_certificate_validation = true`!                                                                                                                              | -                                           |
 | `jwks_uri_backend`           | string                | -                     | [Backend Block Reference](#backend-block)                                      | &#9888; Do not disable the peer certificate validation with `disable_certificate_validation = true`!                                                                                                                              | -                                           |
 | `token_backend`              | string                | -                     | [Backend Block Reference](#backend-block)                                      | &#9888; Do not disable the peer certificate validation with `disable_certificate_validation = true`!                                                                                                                              | -                                           |
@@ -520,8 +525,8 @@ required _label_.
 | `idp_metadata_file` | string | - | File reference to the Identity Provider metadata XML file. | &#9888; required | - |
 | `sp_acs_url`        | string | - | The URL of the Service Provider's ACS endpoint. | &#9888; required. Relative URL references are resolved against the origin of the current request URL. The origin can be changed with the [`accept_forwarded_url`](#settings-block) attribute if Couper is running behind a proxy. | - |
 | `sp_entity_id`      | string | - | The Service Provider's entity ID. |&#9888; required | - |
-| `array_attributes`  | string | `[]` | A list of assertion attributes that may have several values. | Results in at least an empty array in `request.context.<label>.attributes.<name>` | `array_attributes = ["memberOf"]` |
-| `custom_log_fields` | map | - | Defines log fields for [Custom Logging](LOGS.md#custom-logging). | &#9888; Inherited by nested blocks. | - |
+| `array_attributes`  | tuple (string) | `[]` | A list of assertion attributes that may have several values. | Results in at least an empty array in `request.context.<label>.attributes.<name>` | `array_attributes = ["memberOf"]` |
+| `custom_log_fields` | object | - | Defines log fields for [Custom Logging](LOGS.md#custom-logging). | &#9888; Inherited by nested blocks. | - |
 
 Some information from the assertion consumed at the ACS endpoint is provided in the context at `request.context.<label>`:
 
@@ -544,7 +549,7 @@ via `headers` attribute.
 | `expect_status`     | number                | `200`, `204`, `301` | wanted response status code                        |                       | `expect_status =  418`             |
 | `expect_text`       | string                | –                   | text response body must contain                    |                       | `expect_text = alive`              |
 | `failure_threshold` | number                | `2`                 | failed checks needed to consider backend unhealthy |                       | `failure_threshold = 3`            |
-| `headers`           | map                   | –                   | request headers                                    |                       | `headers = {User-Agent: "health"}` |
+| `headers`           | object                | –                   | request headers                                    |                       | `headers = {User-Agent: "health"}` |
 | `interval`          | [duration](#duration) | `"2s"`              | time interval for recheck                          |                       | `timeout = "5s"`                   |
 | `path`              | string                | –                   | URL path/query on backend host                     |                       | `path = "/health"`                 |
 | `timeout`           | [duration](#duration) | `"2s"`              | maximum allowed time limit                         | bounded by `interval` | `timeout = "3s"`                   |
@@ -560,10 +565,10 @@ gateway instance.
 
 | Attribute(s)                    | Type   | Default             | Description | Characteristic(s) | Example |
 |:--------------------------------| :----- | :------------------ | :---------- | :---------------- | :------ |
-| `accept_forwarded_url`          | list   | `[]`                | Which `X-Forwarded-*` request headers should be accepted to change the [request variables](#request) `url`, `origin`, `protocol`, `host`, `port`. Valid values: `proto`, `host`, `port`. The port in `X-Forwarded-Port` takes precedence over a port in `X-Forwarded-Host`. | Affects relative url values for [`sp_acs_url`](#saml-block) attribute and `redirect_uri` attribute within [beta_oauth2](#beta-oauth2-block) & [oidc](#oidc-block). | `["proto","host","port"]` |
+| `accept_forwarded_url`          | tuple (string) | `[]`        | Which `X-Forwarded-*` request headers should be accepted to change the [request variables](#request) `url`, `origin`, `protocol`, `host`, `port`. Valid values: `proto`, `host`, `port`. The port in `X-Forwarded-Port` takes precedence over a port in `X-Forwarded-Host`. | Affects relative url values for [`sp_acs_url`](#saml-block) attribute and `redirect_uri` attribute within [beta_oauth2](#beta-oauth2-block) & [oidc](#oidc-block). | `["proto","host","port"]` |
 | `default_port`                  | number | `8080`              | Port which will be used if not explicitly specified per host within the [`hosts`](#server-block) list. |-|-|
 | `health_path`                   | string | `/healthz`          | Health path which is available for all configured server and ports. |-|-|
-| `https_dev_proxy`               | list   | `[]`                | List of tls port mappings to define the tls listen port and the target one. A self-signed certificate will be generated on the fly based on given hostname. | Certificates will be hold in memory and are generated once. | `["443:8080", "8443:8080"]` |
+| `https_dev_proxy`               | tuple (string)   | `[]`      | List of tls port mappings to define the tls listen port and the target one. A self-signed certificate will be generated on the fly based on given hostname. | Certificates will be hold in memory and are generated once. | `["443:8080", "8443:8080"]` |
 | `log_format`                    | string | `common`            | Switch for tab/field based colored view or json log lines. |-|-|
 | `log_level`                     | string | `info`              | Set the log-level to one of: `info`, `panic`, `fatal`, `error`, `warn`, `debug`, `trace`. |-|-|
 | `log_pretty`                    | bool   | `false`             | Global option for `json` log format which pretty prints with basic key coloring. |-|-|
@@ -589,7 +594,7 @@ The `defaults` block lets you define default values.
 
 | Attribute(s) | Type |Default|Description|Characteristic(s)| Example|
 | :------------------------------ | :--------------- | :--------------- | :--------------- | :--------------- | :--------------- |
-| `environment_variables` | map | – | One or more environment variable assigments|-|`environment_variables = {ORIGIN = "https://httpbin.org" ...}`|
+| `environment_variables` | object (string) | – | One or more environment variable assigments|-|`environment_variables = {ORIGIN = "https://httpbin.org" ...}`|
 
 Examples:
 
@@ -609,7 +614,7 @@ Concerning child blocks and attributes, the `error_handler` block is similar to
 
 | Attribute(s)            | Type             | Default | Description                                                                                                       | Characteristic(s)                                                                                                                                                                                                                                                                                                                                                                                                                               | Example                                                              |
 |:------------------------|:-----------------|:--------|:------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------|
-| `custom_log_fields`     | map              | -       | Defines log fields for [Custom Logging](LOGS.md#custom-logging).                                                  | &#9888; Inherited by nested blocks.                                                                                                                                                                                                                                                                                                                                                                                                             | -                                                                    |
+| `custom_log_fields`     | object           | -       | Defines log fields for [Custom Logging](LOGS.md#custom-logging).                                                  | &#9888; Inherited by nested blocks.                                                                                                                                                                                                                                                                                                                                                                                                             | -                                                                    |
 | [Modifiers](#modifiers) | -                | -       | -                                                                                                                 | -                                                                                                                                                                                                                                                                                                                                                                                                                                               | -                                                                    |
 
 Examples:
@@ -673,12 +678,12 @@ defaults {
 | `method`                         | string          | HTTP method                                                                                                                                                                                                                                                                         | `GET`                                       |
 | `headers.<name>`                 | string          | HTTP request header value for requested lower-case key                                                                                                                                                                                                                              |                                             |
 | `cookies.<name>`                 | string          | Value from `Cookie` request header for requested key (&#9888; last wins!)                                                                                                                                                                                                           |                                             |
-| `query.<name>`                   | tuple of string | Query parameter values                                                                                                                                                                                                                                                              |                                             |
+| `query.<name>`                   | list (string)   | Query parameter values                                                                                                                                                                                                                                                              |                                             |
 | `path_params.<name>`             | string          | Value from a named path parameter defined within an endpoint path label                                                                                                                                                                                                             |                                             |
 | `body`                           | string          | Request message body                                                                                                                                                                                                                                                                |                                             |
-| `form_body.<name>`               | tuple of string | Parameter in a `application/x-www-form-urlencoded` body                                                                                                                                                                                                                             |                                             |
-| `json_body.<name>`               | various         | Access json decoded object properties. Media type must be `application/json` or `application/*+json`.                                                                                                                                                                               |                                             |
-| `context.beta_granted_permissions` | tuple of string | Permissions granted to the requester as yielded by access controls (see e.g. `beta_permissions_claim`, `beta_roles_claim` in the [`jwt` block](#jwt-block)).                                                                                                                      | `["perm1", "perm2"]`                        |
+| `form_body.<name>`               | list (string)   | Parameter in a `application/x-www-form-urlencoded` body                                                                                                                                                                                                                             |                                             |
+| `json_body`                      | various         | Access json decoded message body. Media type must be `application/json` or `application/*+json`.                                                                                                                                                                               |                                             |
+| `context.beta_granted_permissions` | list (string) | Permissions granted to the requester as yielded by access controls (see e.g. `beta_permissions_claim`, `beta_roles_claim` in the [`jwt` block](#jwt-block)).                                                                                                                      | `["perm1", "perm2"]`                        |
 | `context.beta_required_permission` | string        | Permission required to perform the requested operation (value of the `beta_required_permission` attribute of [`endpoint`](#endpoint-block) (or [`api`](#api-block)) block).                                                                                                         |                                             |
 | `context.<name>.<property_name>` | various         | Request context containing information from the [Access Control](#access-control).                                                                                                                                                                                                  |                                             |
 | `url`                            | string          | Request URL                                                                                                                                                                                                                                                                         | `https://www.example.com/path/to?q=val&a=1` |
@@ -740,10 +745,10 @@ To access the HTTP method of the `default` request use `backend_requests.default
 | `method`                         | string          | HTTP method                                                                                                                                                                                                                                                                          | `GET`                                       |
 | `headers.<name>`                 | string          | HTTP request header value for requested lower-case key                                                                                                                                                                                                                               |                                             |
 | `cookies.<name>`                 | string          | Value from `Cookie` request header for requested key (&#9888; last wins!)                                                                                                                                                                                                            |                                             |
-| `query.<name>`                   | tuple of string | Query parameter values                                                                                                                                                                                                                                                               |                                             |
+| `query.<name>`                   | list (string)   | Query parameter values                                                                                                                                                                                                                                                               |                                             |
 | `body`                           | string          | Backend request message body                                                                                                                                                                                                                                                         |                                             |
-| `form_body.<name>`               | tuple of string | Parameter in a `application/x-www-form-urlencoded` body                                                                                                                                                                                                                              |                                             |
-| `json_body.<name>`               | various         | Access json decoded object properties. Media type must be `application/json` or `application/*+json`.                                                                                                                                                                                |                                             |
+| `form_body.<name>`               | list (string)   | Parameter in a `application/x-www-form-urlencoded` body                                                                                                                                                                                                                              |                                             |
+| `json_body`                      | various         | Access json decoded message body. Media type must be `application/json` or `application/*+json`.                                                                                                                                                                                |                                             |
 | `context.<name>.<property_name>` | various         | Request context containing claims from JWT used for [Access Control](#access-control) or information from a SAML assertion, `<name>` being the [JWT Block's](#jwt-block) or [SAML Block's](#saml-block) label and `property_name` being the claim's or assertion information's name  |                                             |
 | `url`                            | string          | Backend request URL                                                                                                                                                                                                                                                                  | `https://www.example.com/path/to?q=val&a=1` |
 | `origin`                         | string          | Origin of the backend request URL                                                                                                                                                                                                                                                    | `https://www.example.com`                   |
@@ -770,7 +775,7 @@ To access the HTTP status code of the `default` response use `backend_responses.
 | `headers.<name>`   | string  | HTTP response header value for requested lower-case key                                               | |
 | `cookies.<name>`   | string  | Value from `Set-Cookie` response header for requested key (&#9888; last wins!)                        | |
 | `body`             | string  | The response message body                                                                             | |
-| `json_body.<name>` | various | Access json decoded object properties. Media type must be `application/json` or `application/*+json`. | |
+| `json_body`        | various | Access json decoded object properties. Media type must be `application/json` or `application/*+json`. | |
 
 ## Functions
 
diff --git a/internal/seetie/convert.go b/internal/seetie/convert.go
index 7531e948..0b648af6 100644
--- a/internal/seetie/convert.go
+++ b/internal/seetie/convert.go
@@ -84,7 +84,19 @@ func ValuesMapToValue(m url.Values) cty.Value {
 	return MapToValue(result)
 }
 
-func ListToValue(l []interface{}) cty.Value {
+func stringListToValue(l []string) cty.Value {
+	if l == nil || len(l) == 0 {
+		return cty.ListValEmpty(cty.String)
+	}
+
+	var list []cty.Value
+	for _, s := range l {
+		list = append(list, cty.StringVal(s))
+	}
+	return cty.ListVal(list)
+}
+
+func listToValue(l []interface{}) cty.Value {
 	var list []cty.Value
 	for _, v := range l {
 		list = append(list, GoToValue(v))
@@ -95,7 +107,7 @@ func ListToValue(l []interface{}) cty.Value {
 func GoToValue(v interface{}) cty.Value {
 	switch v := v.(type) {
 	case string:
-		return cty.StringVal(ToString(v))
+		return cty.StringVal(v)
 	case bool:
 		return cty.BoolVal(v)
 	case int64:
@@ -103,13 +115,9 @@ func GoToValue(v interface{}) cty.Value {
 	case float64:
 		return cty.NumberFloatVal(v)
 	case []string:
-		var list []interface{}
-		for _, s := range v {
-			list = append(list, s)
-		}
-		return ListToValue(list)
+		return stringListToValue(v)
 	case []interface{}:
-		return ListToValue(v)
+		return listToValue(v)
 	case map[string]interface{}:
 		return MapToValue(v)
 	default:
@@ -130,13 +138,9 @@ func MapToValue(m map[string]interface{}) cty.Value {
 		}
 		switch v := v.(type) {
 		case []string:
-			var list []interface{}
-			for _, s := range v {
-				list = append(list, s)
-			}
-			ctyMap[k] = ListToValue(list)
+			ctyMap[k] = stringListToValue(v)
 		case []interface{}:
-			ctyMap[k] = ListToValue(v)
+			ctyMap[k] = listToValue(v)
 		case map[string]interface{}:
 			ctyMap[k] = MapToValue(v)
 		default:


Test patch:
diff --git a/internal/seetie/convert_test.go b/internal/seetie/convert_test.go
new file mode 100644
index 00000000..03d055f7
--- /dev/null
+++ b/internal/seetie/convert_test.go
@@ -0,0 +1,39 @@
+package seetie
+
+import (
+	"fmt"
+	"testing"
+
+	"github.com/zclconf/go-cty/cty"
+)
+
+func Test_stringListToValue(t *testing.T) {
+	tests := []struct {
+		slice []string
+	}{
+		{[]string{"a", "b"}},
+		{[]string{}},
+	}
+
+	for _, tt := range tests {
+		t.Run(fmt.Sprintf("%v", tt.slice), func(subT *testing.T) {
+			val := stringListToValue(tt.slice)
+			valType := val.Type()
+			if !valType.IsListType() {
+				t.Error("Expected value type to be list")
+			}
+			if *valType.ListElementType() != cty.String {
+				t.Error("Expected list to contain string values")
+			}
+			sl := val.AsValueSlice()
+			if len(sl) != len(tt.slice) {
+				t.Errorf("Wrong number of items; want: %d, got: %d", len(tt.slice), len(sl))
+			}
+			for i, v := range tt.slice {
+				if sl[i].AsString() != v {
+					t.Errorf("Wrong item at position %d; want %q, got %q", i, v, sl[i])
+				}
+			}
+		})
+	}
+}