--- layout: docs page_title: Controller configuration description: >- Learn about configuring controller-specific parameters. Understand how to configure the required KMS stanzas, and view a complete configuration example. --- # `controller` stanza The `controller` stanza configures Boundary controller-specific parameters. ```hcl controller { name = "example-controller" description = "An example controller" database { url = "postgresql://:@10.0.0.1:5432/" max_open_connections = 5 } } ``` - `name` - Specifies a unique name of this controller within the Boundary cluster. This value can be a direct name string, can refer to a file on disk (file://) from which an name will be read; or an env var (env://) from which the name will be read. - `description` - Specifies a friendly description of this controller. This value can be a direct description string, can refer to a file on disk (file://) from which a description will be read; or an env var (env://) from which the description will be read. - `database` - Configuration block with two valid parameters for connecting to Postgres: - `url` - Configures the URL for connecting to Postgres. If your Postgres server has TLS disabled, Boundary will not be able to connect by default. To run Boundary without a TLS connection to Postgres (not recommended for production usage), add the `sslmode=disable` parameter to your connection string, such as `url = "postgresql://postgres:boundary@192.168.1.1:5432/boundary?sslmode=disable"` This value can refer to a file on disk (file://) from which a URL will be read; an env var (env://) from which the URL will be read; or a direct database URL (postgres://). Since 0.10.5, this value is re-read on `SIGHUP` to support rotation of the database credential. - `migration_url` - Can be used to specify a different URL for migrations, as that usually requires higher privileges. This value can refer to a file on disk (file://) from which a URL will be read; an env var (env://) from which the URL will be read; or a direct database URL (postgres://). - `max_open_connections` - Can be used to control the maximum number of connections that can be opened by the controller. The minimum number of connections required is 5. Setting this value to 0 will allow the controller to open as many connections as needed. This value can be a string or an integer representing the max number of connections, or a string that can refer to a file on disk (file://) from which the number of connections will be read, or an env var (env://) from which the number of connections will be read. - `max_idle_connections` - Can be used to control the maximum number of idle connections in the idle connection pool. If `max_open_connections` is greater than 0 but less than `max_idle_connections`, then `max_idle_connections` will be reduced to match the `max_open_connections` limit. Setting this value to 0 will mean that no idle connections are retained. If not set or set to less than 0, the default [sql.DB](https://pkg.go.dev/database/sql#DB.SetMaxIdleConns) setting will be used. This value can be a string or an integer representing the max number of connections, or a string that can refer to a file on disk (file://) from which the number of connections will be read, or an env var (env://) from which the number of connections will be read. - `max_idle_time` - Can be used to control the maximum amount of time a connection may be idle. Setting this value to 0 will mean that connections are not closed due to a connections idle time. If not set or set to less than 0, the default [sql.DB](https://pkg.go.dev/database/sql#DB.SetConnMaxIdleTime) setting will be used. This value can be a string representing the duration, or a string that can refer to a file on disk (file://) from which the duration will be read, or an env var (env://) from which the duration will be read. Valid time units are anything specified by Golang's [ParseDuration()](https://golang.org/pkg/time/#ParseDuration) method. - `public_cluster_addr` - Specifies the public host or IP address (and optionally port) at which the controller can be reached _by workers_. This will be used by workers after initial connection to controllers via the worker's `initial_upstreams` block. This defaults to the address of the listener marked for `cluster` purpose. It is used if there is a load balancer in front of multiple Boundary controllers. This is also especially useful for cloud environments that do not bind a publicly accessible IP to a NIC on the host directly, such as an Amazon EIP. This value can be a direct address string, can refer to a file on disk (file://) from which an address will be read; an env var (env://) from which the address will be read; or a [go-sockaddr template](https://godoc.org/github.com/hashicorp/go-sockaddr/template). Note that the address should not include the protocol prefixes like `http://` or `https://`. - `auth_token_time_to_live` - Maximum time to live (TTL) for all auth tokens globally (pertains to all tokens from all auth methods). Valid time units are anything specified by Golang's [ParseDuration()](https://golang.org/pkg/time/#ParseDuration) method. Default is 7 days. Note that you cannot set a maximum time to live for auth tokens in HCP Boundary at this time. For HCP Boundary, all auth tokens' maximum time to live equal the default of 7 days. - `auth_token_time_to_stale` - Maximum time of inactivity for all auth tokens globally (pertains to all tokens from all auth methods). Valid time units are anything specified by Golang's [ParseDuration()](https://golang.org/pkg/time/#ParseDuration) method. Default is 1 day. - `scheduler` - The configuration block that specifies the job scheduler behavior on the controller. - `job_run_interval` - The interval at which the scheduler will call the database to check if there are any jobs that need to run. Default is 1 minute. - `monitor_interval` - The interval at which the scheduler will check and interrupt any defuncted jobs that were running on another scheduler. A job is considered defuncted if it has not reported a status to the database for 5 minutes. Once a job is interrupted it will be run immediate on the first controller available. Default is 30 seconds. - `graceful_shutdown_wait_duration` - Amount of time Boundary will wait before initiating the shutdown procedure, after receiving a shutdown signal. In this state, Boundary still processes requests as normal but replies with `503 Service Unavailable` to any health requests. This is designed to allow an operator to configure load-balancers to preemptively stop new traffic to a Boundary instance that is going away. Valid time units are anything specified by Go's [ParseDuration()](https://golang.org/pkg/time/#ParseDuration) method. Only used when an `ops` listener is set and the Controller is present. Default is 0 seconds. - `api_rate_limit` - Sets limits on the rate of requests for controller API endpoints. This setting can help prevent resources from being overwhelmed with too many requests at a time. The `api_rate_limit` configuration stanza contains the following fields: - `resources` - Specifies the Boundary resource you want to limit rates for. The resource can be `target` or `credential-library`, for example. You can include all resources by using the wildcard `"*"`. - `actions` - Specifies the actions you want to limit on the resource. The actions could be `create`, `list`, or `authorize-session`, for example. You can include all actions by using the wildcard `"*"`. - `per` - Specifies how the limit is allocated. You can choose from the following values: - `total` - Counts all requests, regardless of auth token or IP address. - `ip-address` - Counts requests per IP address. This value lets you limit requests per IP address. - `auth-token` - Counts requests per the user's auth token. This value lets you limit requests per auth token. You can also use the wildcard `"*"` to include all values, but only when `unlimited` is also configured. - `limit` - Specifies the number of requests that are allowed within the `period`. - `period` - Specifies the time window for the `limit`. The limit resets after this period of time has passed. - `unlimited` - Indicates that the corresponding resources and actions should not be rate limited. If you set this value to `true`, you should not specify values for the `limit` and `period` or you will receive an error. For more information about how API rate limiting works, refer to the [API rate limiting](/boundary/docs/api-clients/api#rate-limiting) documentation. - `api_rate_limit_disable` - Disables API rate limiting, if set to `true`. If `api_rate_limit_disable` is set to `true`, and you have provided any `api_rate_limit` stanzas, you will receive an error. - `api_rate_limit_max_quotas` - Specifies the maximum number of API rate limiting quotas that Boundary allows. - `max_page_size` - The max allowed page size when paginating. If a user specifies a page size greater than this number, it will be truncated to this number. This is also used as the default page size for any requests that don't explicitly specify a page size. Default is 1000. ## Signals The `SIGHUP` signal causes a controller to reload its configuration file to pick up any updates to the `database url` value. Any other updated values are ignored. The `SIGTERM` and `SIGINT` signals initiate a graceful shutdown on a controller. A graceful shutdown closes listeners and servers before shutting down the controller. ## KMS configuration The controller requires two KMS stanzas for `root` and `worker-auth` purposes: ```hcl # Root KMS configuration block: this is the root key for Boundary # Use a production KMS such as AWS KMS in production installs kms "aead" { purpose = "root" aead_type = "aes-gcm" key = "sP1fnF5Xz85RrXyELHFeZg9Ad2qt4Z4bgNHVGtD6ung=" key_id = "global_root" } # Worker authorization KMS # Use a production KMS such as AWS KMS for production installs # This key is the same key used in the worker configuration kms "aead" { purpose = "worker-auth" aead_type = "aes-gcm" key = "8fZBjCUfN0TzjEGLQldGY4+iE9AkOvCfjh7+p0GtRBQ=" key_id = "global_worker-auth" } ``` And optionally, a KMS stanza for recovery purpose: ```hcl # Recovery KMS block: configures the recovery key for Boundary # Use a production KMS such as AWS KMS for production installs kms "aead" { purpose = "recovery" aead_type = "aes-gcm" key = "8fZBjCUfN0TzjEGLQldGY4+iE9AkOvCfjh7+p0GtRBQ=" key_id = "global_recovery" } ``` And optionally, a KMS stanza for configuration encryption purpose: ```hcl # Configuration encryption block: decrypts sensitive values in the # configuration file. See `boundary config [encrypt|decrypt] -h`. kms "aead" { purpose = "config" aead_type = "aes-gcm" key = "7xtkEoS5EXPbgynwd+dDLHopaCqK8cq0Rpep4eooaTs=" } ``` And optionally, a KMS stanza to enable the session recording feature: ```hcl # BSR encryption block: encrypts data and checks the integrity # of session recordings. If you do not add a BSR key to your # controller configuration, you cannot enable session recording. kms "aead" { purpose = "bsr" aead_type = "aes-gcm" key = "8Vg!XCbS.fzNKB@Uu.ccB588H#4iyHAd:TpgjuwC/;J;" key_id = "session_recording" } ``` Boundary supports many kinds of KMS integrations. For a complete guide to all available KMS types, see our [KMS documentation](/boundary/docs/configuration/kms). ## Complete configuration example ```hcl # Disable memory lock: https://www.man7.org/linux/man-pages/man2/mlock.2.html disable_mlock = true # Controller configuration block controller { # This name attr must be unique across all controller instances if running in HA mode name = "demo-controller-1" description = "A controller for a demo!" # After receiving a shutdown signal, Boundary will wait 10s before initiating the shutdown process. graceful_shutdown_wait_duration = "10s" # Database URL for postgres. This can be a direct "postgres://" # URL, or it can be "file://" to read the contents of a file to # supply the url, or "env://" to name an environment variable # that contains the URL. database { url = "postgresql://boundary:boundarydemo@postgres.yourdomain.com:5432/boundary" } # Rate limiting examples to conserve controller resources # total limit for all resources and actions api_rate_limit { resources = ["*"] actions = ["*"] per = "total" limit = 500 period = "1s" } # Limit for ip addresses to all resources+actions to prevent a malicious # host that is fabricating tokens, or spamming unauthed endpoints api_rate_limit { resources = ["*"] actions = ["*"] per = "ip-address" limit = 100 period = "1s" } # Limit of all authed requests, to prevent one user consuming all of the total limit api_rate_limit { resources = ["*"] actions = ["*"] per = "auth-token" limit = 100 period = "1s" } } # API listener configuration block listener "tcp" { # Should be the address of the NIC that the controller server will be reached on address = "10.0.0.1" # The purpose of this listener block purpose = "api" tls_disable = false # Uncomment to enable CORS for the Admin UI. Be sure to set the allowed origin(s) # to appropriate values. #cors_enabled = true #cors_allowed_origins = ["https://yourcorp.yourdomain.com", "serve://boundary"] } # Data-plane listener configuration block (used for worker coordination) listener "tcp" { # Should be the IP of the NIC that the worker will connect on address = "10.0.0.1" # The purpose of this listener purpose = "cluster" } listener "tcp" { # Should be the address of the NIC where your external systems' # (eg: Load-Balancer) will connect on. address = "10.0.0.1" # The purpose of this listener block purpose = "ops" tls_disable = false } # Root KMS configuration block: this is the root key for Boundary # Use a production KMS such as AWS KMS in production installs kms "aead" { purpose = "root" aead_type = "aes-gcm" key = "sP1fnF5Xz85RrXyELHFeZg9Ad2qt4Z4bgNHVGtD6ung=" key_id = "global_root" } # Worker authorization KMS # Use a production KMS such as AWS KMS for production installs # This key is the same key used in the worker configuration kms "aead" { purpose = "worker-auth" aead_type = "aes-gcm" key = "8fZBjCUfN0TzjEGLQldGY4+iE9AkOvCfjh7+p0GtRBQ=" key_id = "global_worker-auth" } # Recovery KMS block: configures the recovery key for Boundary # Use a production KMS such as AWS KMS for production installs kms "aead" { purpose = "recovery" aead_type = "aes-gcm" key = "8fZBjCUfN0TzjEGLQldGY4+iE9AkOvCfjh7+p0GtRBQ=" key_id = "global_recovery" } # BSR encryption block: encrypts data and checks the integrity # of session recordings. If you do not add a BSR key to your # controller configuration, you cannot enable session recording. kms "aead" { purpose = "bsr" aead_type = "aes-gcm" key = "8Vg!XCbS.fzNKB@Uu.ccB588H#4iyHAd:TpgjuwC/;J;" key_id = "session_recording" } ```