diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 6c4b0ee2d5..c09d688986 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -405,7 +405,6 @@ jobs:
artifact-name: "boundary_${{ needs.set-product-version.outputs.product-version }}_linux_amd64.zip"
go-version: ${{ needs.product-metadata.outputs.go-version }}
edition: ${{ needs.product-metadata.outputs.product-edition }}
- docker-image-name: ${{ needs.build-docker.outputs.name }}
docker-image-file: "boundary_default_linux_amd64_${{ needs.set-product-version.outputs.product-version }}_${{ github.sha }}.docker.dev.tar"
secrets: inherit
bats:
diff --git a/.github/workflows/enos-run.yml b/.github/workflows/enos-run.yml
index b245383a76..c8f6f3538c 100644
--- a/.github/workflows/enos-run.yml
+++ b/.github/workflows/enos-run.yml
@@ -15,9 +15,6 @@ on:
go-version:
required: true
type: string
- docker-image-name:
- required: false
- type: string
docker-image-file:
required: false
type: string
@@ -96,7 +93,6 @@ jobs:
ENOS_VAR_crt_bundle_path: ./support/boundary.zip
ENOS_VAR_test_email: ${{ secrets.SERVICE_USER_EMAIL }}
ENOS_VAR_boundary_edition: ${{ inputs.edition }}
- ENOS_VAR_boundary_docker_image_name: ${{ inputs.docker-image-name }}
ENOS_VAR_boundary_docker_image_file: ./support/boundary_docker_image.tar
ENOS_VAR_go_version: ${{ inputs.go-version }}
ENOS_VAR_gcp_project_id: ${{ secrets.GCP_PROJECT_ID_CI }}
diff --git a/enos/README.md b/enos/README.md
index 7511d97695..9ecc555977 100644
--- a/enos/README.md
+++ b/enos/README.md
@@ -66,6 +66,8 @@ following lines
127.0.0.1 localhost worker
127.0.0.1 localhost vault
```
+### AWS Credentials
+Copy the AWS Account credentials from doormat and set it in the terminal, where the enos commands are run.
## Executing Scenarios
From the `enos` directory:
diff --git a/enos/enos-scenario-e2e-docker-base-plus.hcl b/enos/enos-scenario-e2e-docker-base-plus.hcl
index 26413d646a..2974fef247 100644
--- a/enos/enos-scenario-e2e-docker-base-plus.hcl
+++ b/enos/enos-scenario-e2e-docker-base-plus.hcl
@@ -81,7 +81,7 @@ scenario "e2e_docker_base_plus" {
step.build_boundary_docker_image
]
variables {
- image_name = matrix.builder == "crt" ? var.boundary_docker_image_name : step.build_boundary_docker_image.image_name
+ image_name = step.build_boundary_docker_image.image_name
network_name = [local.network_cluster]
database_network = local.network_cluster
postgres_address = step.create_boundary_database.address
diff --git a/enos/enos-scenario-e2e-docker-base-with-gcp.hcl b/enos/enos-scenario-e2e-docker-base-with-gcp.hcl
index 106f8590b3..a24e25cda0 100644
--- a/enos/enos-scenario-e2e-docker-base-with-gcp.hcl
+++ b/enos/enos-scenario-e2e-docker-base-with-gcp.hcl
@@ -82,7 +82,7 @@ scenario "e2e_docker_base_with_gcp" {
step.build_boundary_docker_image
]
variables {
- image_name = matrix.builder == "crt" ? var.boundary_docker_image_name : step.build_boundary_docker_image.image_name
+ image_name = step.build_boundary_docker_image.image_name
network_name = [local.network_cluster]
database_network = local.network_cluster
postgres_address = step.create_boundary_database.address
diff --git a/enos/enos-scenario-e2e-docker-base-with-vault.hcl b/enos/enos-scenario-e2e-docker-base-with-vault.hcl
index 4e19859f42..6b8cd1c306 100644
--- a/enos/enos-scenario-e2e-docker-base-with-vault.hcl
+++ b/enos/enos-scenario-e2e-docker-base-with-vault.hcl
@@ -83,7 +83,7 @@ scenario "e2e_docker_base_with_vault" {
step.build_boundary_docker_image
]
variables {
- image_name = matrix.builder == "crt" ? var.boundary_docker_image_name : step.build_boundary_docker_image.image_name
+ image_name = step.build_boundary_docker_image.image_name
network_name = [local.network_cluster]
database_network = local.network_cluster
postgres_address = step.create_boundary_database.address
diff --git a/enos/enos-scenario-e2e-docker-base-with-worker.hcl b/enos/enos-scenario-e2e-docker-base-with-worker.hcl
index 0fda20cf29..ad398c821b 100644
--- a/enos/enos-scenario-e2e-docker-base-with-worker.hcl
+++ b/enos/enos-scenario-e2e-docker-base-with-worker.hcl
@@ -99,7 +99,7 @@ scenario "e2e_docker_base_with_worker" {
step.build_boundary_docker_image
]
variables {
- image_name = matrix.builder == "crt" ? var.boundary_docker_image_name : step.build_boundary_docker_image.image_name
+ image_name = step.build_boundary_docker_image.image_name
network_name = [local.network_cluster, local.network_database]
database_network = local.network_database
postgres_address = step.create_boundary_database.address
@@ -143,7 +143,7 @@ scenario "e2e_docker_base_with_worker" {
step.create_boundary
]
variables {
- image_name = matrix.builder == "crt" ? var.boundary_docker_image_name : step.build_boundary_docker_image.image_name
+ image_name = step.build_boundary_docker_image.image_name
boundary_license = var.boundary_edition != "oss" ? step.read_license.license : ""
config_file = "worker-config.hcl"
container_name = "worker"
diff --git a/enos/enos-scenario-e2e-docker-base.hcl b/enos/enos-scenario-e2e-docker-base.hcl
index e4ae9cdeb6..a57b865411 100644
--- a/enos/enos-scenario-e2e-docker-base.hcl
+++ b/enos/enos-scenario-e2e-docker-base.hcl
@@ -81,7 +81,7 @@ scenario "e2e_docker_base" {
step.build_boundary_docker_image
]
variables {
- image_name = matrix.builder == "crt" ? var.boundary_docker_image_name : step.build_boundary_docker_image.image_name
+ image_name = step.build_boundary_docker_image.image_name
network_name = [local.network_cluster]
database_network = local.network_cluster
postgres_address = step.create_boundary_database.address
diff --git a/enos/enos-scenario-e2e-docker-worker-registration-controller-led.hcl b/enos/enos-scenario-e2e-docker-worker-registration-controller-led.hcl
index 15dc01b90a..451c4a0eec 100644
--- a/enos/enos-scenario-e2e-docker-worker-registration-controller-led.hcl
+++ b/enos/enos-scenario-e2e-docker-worker-registration-controller-led.hcl
@@ -99,7 +99,7 @@ scenario "e2e_docker_worker_registration_controller_led" {
step.build_boundary_docker_image
]
variables {
- image_name = matrix.builder == "crt" ? var.boundary_docker_image_name : step.build_boundary_docker_image.image_name
+ image_name = step.build_boundary_docker_image.image_name
network_name = [local.network_cluster, local.network_database]
database_network = local.network_database
postgres_address = step.create_boundary_database.address
@@ -113,7 +113,7 @@ scenario "e2e_docker_worker_registration_controller_led" {
depends_on = [step.create_boundary]
variables {
address = step.create_boundary.address
- image_name = matrix.builder == "crt" ? var.boundary_docker_image_name : step.build_boundary_docker_image.image_name
+ image_name = step.build_boundary_docker_image.image_name
network_name = local.network_cluster
login_name = step.create_boundary.login_name
password = step.create_boundary.password
@@ -157,7 +157,7 @@ scenario "e2e_docker_worker_registration_controller_led" {
step.create_boundary
]
variables {
- image_name = matrix.builder == "crt" ? var.boundary_docker_image_name : step.build_boundary_docker_image.image_name
+ image_name = step.build_boundary_docker_image.image_name
boundary_license = var.boundary_edition != "oss" ? step.read_license.license : ""
config_file = "worker-config-controller-led.hcl"
container_name = "worker"
diff --git a/enos/enos-scenario-e2e-docker-worker-registration-worker-led.hcl b/enos/enos-scenario-e2e-docker-worker-registration-worker-led.hcl
index 93651ecbd4..208a0850f4 100644
--- a/enos/enos-scenario-e2e-docker-worker-registration-worker-led.hcl
+++ b/enos/enos-scenario-e2e-docker-worker-registration-worker-led.hcl
@@ -99,7 +99,7 @@ scenario "e2e_docker_worker_registration_worker_led" {
step.build_boundary_docker_image
]
variables {
- image_name = matrix.builder == "crt" ? var.boundary_docker_image_name : step.build_boundary_docker_image.image_name
+ image_name = step.build_boundary_docker_image.image_name
network_name = [local.network_cluster, local.network_database]
database_network = local.network_database
postgres_address = step.create_boundary_database.address
@@ -144,7 +144,7 @@ scenario "e2e_docker_worker_registration_worker_led" {
step.create_boundary
]
variables {
- image_name = matrix.builder == "crt" ? var.boundary_docker_image_name : step.build_boundary_docker_image.image_name
+ image_name = step.build_boundary_docker_image.image_name
boundary_license = var.boundary_edition != "oss" ? step.read_license.license : ""
config_file = "worker-config-worker-led.hcl"
container_name = "worker"
@@ -165,7 +165,7 @@ scenario "e2e_docker_worker_registration_worker_led" {
]
variables {
address = step.create_boundary.address
- image_name = matrix.builder == "crt" ? var.boundary_docker_image_name : step.build_boundary_docker_image.image_name
+ image_name = step.build_boundary_docker_image.image_name
network_name = local.network_cluster
login_name = step.create_boundary.login_name
password = step.create_boundary.password
diff --git a/enos/enos-scenario-e2e-ui-docker.hcl b/enos/enos-scenario-e2e-ui-docker.hcl
index 7128afe10a..7acc96c9fd 100644
--- a/enos/enos-scenario-e2e-ui-docker.hcl
+++ b/enos/enos-scenario-e2e-ui-docker.hcl
@@ -81,7 +81,7 @@ scenario "e2e_ui_docker" {
step.build_boundary_docker_image
]
variables {
- image_name = matrix.builder == "crt" ? var.boundary_docker_image_name : step.build_boundary_docker_image.image_name
+ image_name = step.build_boundary_docker_image.image_name
network_name = [local.network_cluster]
database_network = local.network_cluster
postgres_address = step.create_boundary_database.address
@@ -124,7 +124,7 @@ scenario "e2e_ui_docker" {
step.create_boundary
]
variables {
- image_name = matrix.builder == "crt" ? var.boundary_docker_image_name : step.build_boundary_docker_image.image_name
+ image_name = step.build_boundary_docker_image.image_name
boundary_license = var.boundary_edition != "oss" ? step.read_license.license : ""
config_file = "worker-config.hcl"
container_name = "worker"
diff --git a/enos/enos-variables.hcl b/enos/enos-variables.hcl
index c8e4021557..4bcac203af 100644
--- a/enos/enos-variables.hcl
+++ b/enos/enos-variables.hcl
@@ -25,12 +25,6 @@ variable "enos_user" {
}
# Test configs
-variable "boundary_docker_image_name" {
- description = "Name:Tag of Docker image to use"
- type = string
- default = "docker.io/hashicorp/boundary:latest"
-}
-
variable "boundary_docker_image_file" {
description = "Path to Boundary Docker image"
type = string
diff --git a/enos/modules/aws_boundary/boundary-instances.tf b/enos/modules/aws_boundary/boundary-instances.tf
index 7362884e6b..3f4bd7a204 100644
--- a/enos/modules/aws_boundary/boundary-instances.tf
+++ b/enos/modules/aws_boundary/boundary-instances.tf
@@ -26,6 +26,11 @@ resource "aws_instance" "controller" {
encrypted = true
}
+ metadata_options {
+ http_endpoint = "enabled"
+ http_tokens = "required"
+ }
+
tags = merge(local.common_tags,
{
Name = "${local.name_prefix}-boundary-controller-${count.index}-${split(":", data.aws_caller_identity.current.user_id)[1]}"
@@ -54,6 +59,11 @@ resource "aws_instance" "worker" {
encrypted = true
}
+ metadata_options {
+ http_endpoint = "enabled"
+ http_tokens = "required"
+ }
+
tags = merge(local.common_tags,
{
Name = "${local.name_prefix}-boundary-worker-${count.index}-${split(":", data.aws_caller_identity.current.user_id)[1]}",
diff --git a/enos/modules/aws_boundary/rds.tf b/enos/modules/aws_boundary/rds.tf
index 76f5335b99..699866d366 100644
--- a/enos/modules/aws_boundary/rds.tf
+++ b/enos/modules/aws_boundary/rds.tf
@@ -6,14 +6,18 @@ resource "aws_db_subnet_group" "boundary" {
subnet_ids = data.aws_subnets.infra.ids
}
+data "aws_rds_engine_version" "default" {
+ engine = var.db_engine
+}
+
resource "aws_db_instance" "boundary" {
count = var.db_create == true ? 1 : 0
identifier = "boundary-db-${random_string.cluster_id.result}"
allocated_storage = var.db_storage
storage_type = var.db_storage_type
iops = var.db_storage_iops
- engine = var.db_engine
- engine_version = var.db_engine == "aurora-postgres" ? null : var.db_version
+ engine = data.aws_rds_engine_version.default.engine
+ engine_version = data.aws_rds_engine_version.default.version
instance_class = var.db_class
monitoring_interval = var.db_monitoring_interval
monitoring_role_arn = var.db_monitoring_role_arn
diff --git a/enos/modules/aws_boundary/variables.tf b/enos/modules/aws_boundary/variables.tf
index 81ffe02676..5a55a00a6e 100644
--- a/enos/modules/aws_boundary/variables.tf
+++ b/enos/modules/aws_boundary/variables.tf
@@ -136,12 +136,6 @@ variable "db_class" {
default = "db.t4g.small"
}
-variable "db_version" {
- description = "AWS RDS DBS engine version (for postgres/mysql)"
- type = string
- default = "15.7"
-}
-
variable "db_engine" {
description = "AWS RDS DB engine type"
type = string
@@ -406,4 +400,4 @@ variable "vault_transit_token" {
description = "vault token used for kms transit in the boundary config"
type = string
default = ""
-}
\ No newline at end of file
+}
diff --git a/enos/modules/aws_rdp_domain_controller/main.tf b/enos/modules/aws_rdp_domain_controller/main.tf
index 931ef40087..8516313aa0 100644
--- a/enos/modules/aws_rdp_domain_controller/main.tf
+++ b/enos/modules/aws_rdp_domain_controller/main.tf
@@ -302,6 +302,7 @@ resource "aws_instance" "domain_controller" {
metadata_options {
http_endpoint = "enabled"
+ http_tokens = "required"
instance_metadata_tags = "enabled"
}
get_password_data = true
diff --git a/enos/modules/aws_rdp_member_server/main.tf b/enos/modules/aws_rdp_member_server/main.tf
index 86b5ba6878..1b712788d8 100644
--- a/enos/modules/aws_rdp_member_server/main.tf
+++ b/enos/modules/aws_rdp_member_server/main.tf
@@ -234,6 +234,7 @@ ${var.domain_admin_password}
metadata_options {
http_endpoint = "enabled"
+ http_tokens = "required"
instance_metadata_tags = "enabled"
}
get_password_data = true
diff --git a/enos/modules/aws_rdp_member_server_with_worker/main.tf b/enos/modules/aws_rdp_member_server_with_worker/main.tf
index ccd2ad5a32..3b91f6234b 100644
--- a/enos/modules/aws_rdp_member_server_with_worker/main.tf
+++ b/enos/modules/aws_rdp_member_server_with_worker/main.tf
@@ -251,6 +251,7 @@ ${var.domain_admin_password}
metadata_options {
http_endpoint = "enabled"
+ http_tokens = "required"
instance_metadata_tags = "enabled"
}
get_password_data = true
diff --git a/enos/modules/aws_target/main.tf b/enos/modules/aws_target/main.tf
index 2179a550b0..e7694cf9b1 100644
--- a/enos/modules/aws_target/main.tf
+++ b/enos/modules/aws_target/main.tf
@@ -126,13 +126,18 @@ resource "aws_instance" "target" {
"Type" : "target",
"Project" : "Enos",
"Project Name" : "qti-enos-boundary",
- "Environment" : var.environment
+ "Environment" : var.environment,
"Enos User" : var.enos_user,
})
root_block_device {
encrypted = true
}
+
+ metadata_options {
+ http_endpoint = "enabled"
+ http_tokens = "required"
+ }
}
resource "enos_remote_exec" "wait" {
diff --git a/enos/modules/aws_vault/vault-instances.tf b/enos/modules/aws_vault/vault-instances.tf
index 2fd1b092c4..8ed35ce60a 100644
--- a/enos/modules/aws_vault/vault-instances.tf
+++ b/enos/modules/aws_vault/vault-instances.tf
@@ -17,6 +17,11 @@ resource "aws_instance" "vault_instance" {
Type = local.vault_cluster_tag
},
)
+
+ metadata_options {
+ http_endpoint = "enabled"
+ http_tokens = "required"
+ }
}
resource "enos_remote_exec" "install_dependencies" {
diff --git a/enos/modules/aws_windows_client/main.tf b/enos/modules/aws_windows_client/main.tf
index 837a9dbc6e..b616ef88be 100644
--- a/enos/modules/aws_windows_client/main.tf
+++ b/enos/modules/aws_windows_client/main.tf
@@ -253,6 +253,7 @@ resource "aws_instance" "client" {
metadata_options {
http_endpoint = "enabled"
+ http_tokens = "required"
instance_metadata_tags = "enabled"
}
get_password_data = true
diff --git a/enos/modules/aws_worker/main.tf b/enos/modules/aws_worker/main.tf
index a7ba4d11e1..e92061a439 100644
--- a/enos/modules/aws_worker/main.tf
+++ b/enos/modules/aws_worker/main.tf
@@ -161,6 +161,11 @@ resource "aws_instance" "worker" {
Name = "${var.name_prefix}-boundary-worker-${split(":", data.aws_caller_identity.current.user_id)[1]}",
},
)
+
+ metadata_options {
+ http_endpoint = "enabled"
+ http_tokens = "required"
+ }
}
resource "enos_bundle_install" "worker" {
diff --git a/enos/modules/build_boundary_docker_crt/main.tf b/enos/modules/build_boundary_docker_crt/main.tf
index 1f27ee6041..d8d80e3ccc 100644
--- a/enos/modules/build_boundary_docker_crt/main.tf
+++ b/enos/modules/build_boundary_docker_crt/main.tf
@@ -27,6 +27,21 @@ resource "enos_local_exec" "load_docker_image" {
inline = ["docker load -i ${var.path}"]
}
+locals {
+ boundary_docker_image_name = replace(
+ element(
+ split("\n", trimspace(enos_local_exec.load_docker_image.stdout)),
+ -1
+ ),
+ "Loaded image: ",
+ ""
+ )
+}
+
output "cli_zip_path" {
value = var.cli_build_path
}
+
+output "image_name" {
+ value = local.boundary_docker_image_name
+}
diff --git a/internal/daemon/worker/handler.go b/internal/daemon/worker/handler.go
index a0d0691166..96781d6aaa 100644
--- a/internal/daemon/worker/handler.go
+++ b/internal/daemon/worker/handler.go
@@ -283,7 +283,15 @@ func (w *Worker) handleProxy(listenerCfg *listenerutil.ListenerConfig, sessionMa
runProxy, err := handleProxyFn(ctx, ctx, decryptFn, cc, pDialer, acResp.GetConnectionId(), protocolCtx, w.recorderManager, proxyHandlers.WithLogger(w.logger))
if err != nil {
conn.Close(proxyHandlers.WebsocketStatusProtocolSetupError, "unable to setup proxying")
- event.WriteError(ctx, op, err)
+
+ switch {
+ case errors.Match(errors.T(errors.WindowsRDPClientEarlyDisconnection), err):
+ // This is known behavior with Windows Remote Desktop clients and does not
+ // indicate a problem with the worker or the proxy.
+ // There is no need to log an error event here.
+ default:
+ event.WriteError(ctx, op, err)
+ }
return
}
diff --git a/internal/errors/code.go b/internal/errors/code.go
index 222dbfcbd0..3aac53406d 100644
--- a/internal/errors/code.go
+++ b/internal/errors/code.go
@@ -69,6 +69,9 @@ const (
InvalidListToken Code = 136 // InvalidListToken represents an error where the provided list token is invalid
Paused Code = 137 // Paused represents an error when an operation cannot be completed because the thing being operated on is paused
+ // Note: Currently unused in OSS
+ WindowsRDPClientEarlyDisconnection Code = 138 // WindowsRDPClientEarlyDisconnection represents an error when a Windows RDP client disconnects early, a known behavior with Windows Remote Desktop clients
+
AuthAttemptExpired Code = 198 // AuthAttemptExpired represents an expired authentication attempt
AuthMethodInactive Code = 199 // AuthMethodInactive represents an error that means the auth method is not active.
diff --git a/internal/errors/code_test.go b/internal/errors/code_test.go
index 6afd68d2d4..c19aa8375d 100644
--- a/internal/errors/code_test.go
+++ b/internal/errors/code_test.go
@@ -455,6 +455,11 @@ func TestCode_Both_String_Info(t *testing.T) {
c: Paused,
want: Paused,
},
+ {
+ name: "WindowsRDPClientEarlyDisconnection",
+ c: WindowsRDPClientEarlyDisconnection,
+ want: WindowsRDPClientEarlyDisconnection,
+ },
{
name: "ImmutableColumn",
c: ImmutableColumn,
diff --git a/internal/errors/info.go b/internal/errors/info.go
index ce2e1f89e4..e54ba27933 100644
--- a/internal/errors/info.go
+++ b/internal/errors/info.go
@@ -347,6 +347,10 @@ var errorCodeInfo = map[Code]Info{
Message: "paused",
Kind: State,
},
+ WindowsRDPClientEarlyDisconnection: {
+ Message: "rdp client disconnected early",
+ Kind: State,
+ },
ExternalPlugin: {
Message: "plugin error",
Kind: External,
diff --git a/internal/gen/controller.swagger.json b/internal/gen/controller.swagger.json
index 1dd3cbf431..14082834ed 100644
--- a/internal/gen/controller.swagger.json
+++ b/internal/gen/controller.swagger.json
@@ -3,7 +3,7 @@
"info": {
"title": "Boundary controller HTTP API",
"description": "Welcome to the Boundary controller HTTP API documentation. This page provides a reference guide for using the Boundary controller API, a JSON-based HTTP API. The API implements commonly seen HTTP API patterns for status codes, paths, and errors. See the [API overview](https://developer.hashicorp.com/boundary/docs/api-clients/api) for more information.\n\nBefore you read this page, it is useful to understand Boundary's [domain model](https://developer.hashicorp.com/boundary/docs/concepts/domain-model) and to be aware of the terminology used here. To get started, search for the service you want to interact with in the sidebar to the left. Each resource in Boundary, such as accounts and credential stores, has its own service. Each service contains all the API endpoints for the resource.\n## Status codes\n- `2XX`: Boundary returns a code between `200` and `299` on success. Generally this is `200`, but implementations should be prepared to accept any `2XX` status code as indicating success. If a call returns a `2XX` code that is not `200`, it follows well-understood semantics for those status codes.\n- `400`: Boundary returns `400` when a command cannot be completed due to invalid user input, except for a properly-formatted identifier that does not map to an existing resource, which returns a `404` as discussed below.\n- `401`: Boundary returns `401` if no authentication token is provided or if the provided token is invalid. A valid token that simply does not have permission for a resource returns a `403` instead. A token that is invalid or missing, but where the anonymous user (`u_anon`) is able to successfully perform the action, will not return a `401` but instead will return the result of the action.\n- `403`: Boundary returns `403` if a provided token was valid but does not have the grants required to perform the requested action.\n- `404`: Boundary returns `404` if a resource cannot be found. Note that this happens _prior_ to authentication/authorization checking in nearly all cases as the resource information (such as its scope, available actions, etc.) is a required part of that check. As a result, an action against a resource that does not exist returns a `404` instead of a `401` or `403`. While this could be considered an information leak, since IDs are randomly generated and this only discloses whether an ID is valid, it's tolerable as it allows for far simpler and more robust client implementation.\n- `405`: Boundary returns a `405` to indicate that the method (HTTP verb or custom action) is not implemented for the given resource.\n- `429`: Boundary returns a `429` if any of the API rate limit quotas have been exhausted for the resource and action. It includes the `Retry-After` header so that the client knows how long to wait before making a new request.\n- `500`: Boundary returns `500` if an error occurred that is not (directly) tied to invalid user input. If a `500` is generated, information about the error is logged to Boundary's server log but is not generally provided to the client.\n- `503`: Boundary returns a `503` if it is unable to store a quota due to the API rate limit being exceeded. It includes the `Retry-After` header so that the client knows how long to wait before making a new request.\n## List pagination\nBoundary uses [API pagination](https://developer.hashicorp.com/boundary/docs/api-clients/api/pagination) to support searching and filtering large lists of results efficiently.",
- "version": "0.20.0",
+ "version": "0.20.1",
"contact": {
"name": "HashiCorp Boundary",
"url": "https://www.boundaryproject.io/"
diff --git a/version/VERSION b/version/VERSION
index a881cf79f2..9d2632160c 100644
--- a/version/VERSION
+++ b/version/VERSION
@@ -1 +1 @@
-0.20.0
\ No newline at end of file
+0.20.1
\ No newline at end of file
diff --git a/website/content/docs/api-clients/desktop.mdx b/website/content/docs/api-clients/desktop.mdx
index ba74487f21..d4e0d8be98 100644
--- a/website/content/docs/api-clients/desktop.mdx
+++ b/website/content/docs/api-clients/desktop.mdx
@@ -10,7 +10,7 @@ description: >-
Boundary Desktop is a standalone application that provides a simple interface
for browsing and connecting to targets on your local computer (macOS and Windows
currently supported). Launch a session in Boundary Desktop and then make a connection
-using your favorite tooling!
+using your favorite tooling.
## Get started
diff --git a/website/content/docs/api/index.mdx b/website/content/docs/api/index.mdx
index caafd12f75..069e10dad0 100644
--- a/website/content/docs/api/index.mdx
+++ b/website/content/docs/api/index.mdx
@@ -13,7 +13,11 @@ Before reading this page, it is useful to understand Boundary's [domain model](/
Boundary's API is also described via OpenAPI v2; the version corresponding to any tag of Boundary's source code can be found in Boundary's [GitHub repository](https://github.com/hashicorp/boundary/blob/main/internal/gen/controller.swagger.json).
--> **NOTE:** A rendered version of this generated API definition can be found on the [API page](/boundary/api-docs).
+
+
+Refer to the [API page](/boundary/api-docs) for a rendered version of this generated API definition.
+
+
Boundary's current API version is 1; all API paths begin with `/v1/`.
diff --git a/website/content/docs/architecture/high-availability.mdx b/website/content/docs/architecture/high-availability.mdx
index 6c57ec41bf..ab7eabe200 100644
--- a/website/content/docs/architecture/high-availability.mdx
+++ b/website/content/docs/architecture/high-availability.mdx
@@ -24,6 +24,8 @@ The following ports should be available:
The general architecture for the server infrastructure requires 3 controllers and 3 workers. Note that it is possible to run a controller and worker within the same process, but the guide here assumes separate deployments. The documentation here uses virtual machines running on Amazon EC2 as the example environment, but this use case can be extrapolated to almost any cloud platform to suit operator needs:

+
+
As shown above, Boundary is broken up into its controller and worker server components across 3 [EC2 instances](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance), in
3 separate [subnets](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/subnet), in three separate availability zones, with the controller API and UI being publically exposed by an [application load balancer (ALB)](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb). The worker and controller VM's are in independent [auto-scaling groups](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_group), allowing them to maintain their exact capacity.
diff --git a/website/content/docs/client-agent/troubleshoot.mdx b/website/content/docs/client-agent/troubleshoot.mdx
index 0a4f9ea0c6..5720a12bfd 100644
--- a/website/content/docs/client-agent/troubleshoot.mdx
+++ b/website/content/docs/client-agent/troubleshoot.mdx
@@ -273,7 +273,7 @@ Refer to the following table for known issues with the Client Agent that may aff
| Issue | Description |
| ----- | ----------- |
-| SSH connection fails with man-in-the-middle warning | On Linux systems, the initial transparent session may be successful, but any subsequent connections prompt a warning that you may be experiencing a man-in-the-middle attack.
For more information, refer to [WARNING! Remote host indentification has changed! It is possible that someone is doing something nasty!](/boundary/docs/api-clients/client-agent#warning-remote-host-indentification-has-changed-it-is-possible-that-someone-is-doing-something-nasty) in the **Common error messages** section.|
+| SSH connection fails with man-in-the-middle warning | On Linux systems, the initial transparent session may be successful, but any subsequent connections prompt a warning that you may be experiencing a man-in-the-middle attack.
For more information, refer to [WARNING! Remote host indentification has changed! It is possible that someone is doing something nasty!](/boundary/docs/client-agent/troubleshoot#warning-remote-host-indentification-has-changed-it-is-possible-that-someone-is-doing-something-nasty) in the **Common error messages** section.|
| Boundary Client Agent authentication does not persist across restarts | When you reboot, you are required to re-authenticate to the Client Agent before you can use transparent sessions. |
| Windows installer prompts for restart | When you install Boundary, the Windows installer occasionally prompts you to restart your computer, however it is not necessary. |
| Boundary Client Agent resumes on reboot | If the Client Agent is paused and the machine is rebooted, the Client Agent will be resumed after the reboot. |
diff --git a/website/content/docs/configuration/kms/aead.mdx b/website/content/docs/configuration/kms/aead.mdx
index d6e29dd4bf..e3b77bd526 100644
--- a/website/content/docs/configuration/kms/aead.mdx
+++ b/website/content/docs/configuration/kms/aead.mdx
@@ -29,3 +29,5 @@ kms "aead" {
- `key` - The base64-encoded 256-bit encryption key.
- `key_id` - The unique name of this key.
+It is used to identify the key when you perform a root key migration.
+You can use the `key_id` field with all KMS stanzas.
diff --git a/website/content/docs/configuration/kms/alicloudkms.mdx b/website/content/docs/configuration/kms/alicloudkms.mdx
index 5c941ef8fa..78a0b25b47 100644
--- a/website/content/docs/configuration/kms/alicloudkms.mdx
+++ b/website/content/docs/configuration/kms/alicloudkms.mdx
@@ -24,6 +24,7 @@ kms "alicloudkms" {
access_key = "0wNEpMMlzy7szvai"
secret_key = "PupkTg8jdmau1cXxYacgE736PJj4cA"
kms_key_id = "08c33a6f-4e0a-4a1b-a3fa-7ddfa1d4fb73"
+ key_id = "global_worker-auth"
}
```
@@ -54,6 +55,10 @@ These parameters apply to the `kms` stanza in the Boundary configuration file:
and decryption. May also be specified by the `ALICLOUDKMS_WRAPPER_KEY_ID`
environment variable.
+- `key_id` - The unique name of this key.
+It is used to identify the key when you perform a root key migration.
+You can use the `key_id` field with all KMS stanzas.
+
## Authentication
Authentication-related values must be provided, either as environment
diff --git a/website/content/docs/configuration/kms/awskms.mdx b/website/content/docs/configuration/kms/awskms.mdx
index 72a3e8a808..667f3dea5e 100644
--- a/website/content/docs/configuration/kms/awskms.mdx
+++ b/website/content/docs/configuration/kms/awskms.mdx
@@ -22,6 +22,7 @@ kms "awskms" {
secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
kms_key_id = "19ec80b0-dfdd-4d97-8164-c6examplekey"
endpoint = "https://vpce-0e1bb1852241f8cc6-pzi0do8n.kms.us-east-1.vpce.amazonaws.com"
+ key_id = "global_worker-auth"
}
```
@@ -78,6 +79,10 @@ These parameters apply to the `kms` stanza in the Boundary configuration file:
Endpoint](https://docs.aws.amazon.com/kms/latest/developerguide/kms-vpc-endpoint.html).
If not set, Boundary will use the default API endpoint for your region.
+- `key_id` - The unique name of this key.
+It is used to identify the key when you perform a root key migration.
+You can use the `key_id` field with all KMS stanzas.
+
## Authentication
Authentication-related values must be provided, either as environment
diff --git a/website/content/docs/configuration/kms/azurekeyvault.mdx b/website/content/docs/configuration/kms/azurekeyvault.mdx
index 66b9275f16..bd9d657e98 100644
--- a/website/content/docs/configuration/kms/azurekeyvault.mdx
+++ b/website/content/docs/configuration/kms/azurekeyvault.mdx
@@ -25,6 +25,7 @@ kms "azurekeyvault" {
client_secret = "DUJDS3..."
vault_name = "hc-vault"
key_name = "vault_key"
+ key_id = "global_worker-auth"
}
```
@@ -53,6 +54,10 @@ These parameters apply to the `kms` stanza in the Vault configuration file:
- `key_name` `(string: )`: The Key Vault key to use for encryption and decryption. May also be specified by the
`AZUREKEYVAULT_WRAPPER_KEY_NAME` environment variable.
+- `key_id` - The unique name of this key.
+It is used to identify the key when you perform a root key migration.
+You can use the `key_id` field with all KMS stanzas.
+
## Authentication
Authentication-related values must be provided, either as environment
diff --git a/website/content/docs/configuration/kms/gcpckms.mdx b/website/content/docs/configuration/kms/gcpckms.mdx
index 5ff0f21ab5..d9a4f58fbe 100644
--- a/website/content/docs/configuration/kms/gcpckms.mdx
+++ b/website/content/docs/configuration/kms/gcpckms.mdx
@@ -24,6 +24,7 @@ kms "gcpckms" {
region = "global"
key_ring = "boundary-keyring"
crypto_key = "boundary-key"
+ key_id = "global_worker-auth"
}
```
@@ -53,6 +54,10 @@ These parameters apply to the `kms` stanza in the Boundary configuration file:
encryption and decryption. May also be specified by the `GCPCKMS_WRAPPER_CRYPTO_KEY`
environment variable.
+- `key_id` - The unique name of this key.
+It is used to identify the key when you perform a root key migration.
+You can use the `key_id` field with all KMS stanzas.
+
## Authentication & permissions
Authentication-related values must be provided, either as environment
diff --git a/website/content/docs/configuration/kms/transit.mdx b/website/content/docs/configuration/kms/transit.mdx
index 891ea9b16a..f3086c1d3c 100644
--- a/website/content/docs/configuration/kms/transit.mdx
+++ b/website/content/docs/configuration/kms/transit.mdx
@@ -22,6 +22,7 @@ kms "transit" {
address = "https://vault:8200"
token = "s.Qf1s5zigZ4OX6akYjQXJC1jY"
disable_renewal = "false"
+ key_id = "global_worker-auth"
// Key configuration
key_name = "transit_key_name"
@@ -87,6 +88,10 @@ These parameters apply to the `kms` stanza in the Vault configuration file:
transmissions to and from the Vault server. This may also be specified using the
`VAULT_SKIP_VERIFY` environment variable.
+- `key_id` - The unique name of this key.
+It is used to identify the key when you perform a root key migration.
+You can use the `key_id` field with all KMS stanzas.
+
## Authentication
Authentication-related values must be provided, either as environment
diff --git a/website/content/docs/credentials/static-cred-boundary.mdx b/website/content/docs/credentials/static-cred-boundary.mdx
index 89f73698e1..f26fff08d3 100644
--- a/website/content/docs/credentials/static-cred-boundary.mdx
+++ b/website/content/docs/credentials/static-cred-boundary.mdx
@@ -121,6 +121,6 @@ When you use credential brokering, Boundary centrally manages credentials and re
Credential injection requires HCP Boundary or Boundary Enterprise, and it provides end users with a passwordless experience when they connect to targets.
- [Configure a target for credential brokering](/boundary/docs/credentials/configure-credential-brokering)
-- [Configure a target for credential injection](/boundary/docs/credentials/configure-credential-brokering)
+- [Configure a target for credential injection](/boundary/docs/credentials/configure-credential-injection)
To learn more about what is supported for the RDP credential injection beta and to view known issues, refer to [RDP credential injection compatibility](/boundary/docs/credentials/rdp-testing-and-compatibility-matrix).
\ No newline at end of file
diff --git a/website/content/docs/domain-model/credential-libraries.mdx b/website/content/docs/domain-model/credential-libraries.mdx
index b6216d8c17..d08b57240b 100644
--- a/website/content/docs/domain-model/credential-libraries.mdx
+++ b/website/content/docs/domain-model/credential-libraries.mdx
@@ -59,7 +59,7 @@ Alternatively, you could set the `session_connection_limit` to `1` for any targe
- `vault-path` - (required) The path in Vault to request credentials from.
- `username` - (required) The username to use with the SSH certificate.
-You can create a template for this value using [Vault credential library parameter templating](#vault-credential-library-parameter-templating).
+You can create a template for this value using [Vault credential library parameter templating](#vault-generic-credential-library-parameter-templating).
- `key_type` - (optional) The type of key to use for the generated SSH private key.
The key type is either `ed25519`, `ecdsa`, or `rsa`.
@@ -73,7 +73,7 @@ The number of bits depends on the `key_type` value you select:
- `ttl` - (optional) The SSH certificate's time-to-live (TTL).
-- `key_id` - (optional) The key ID for the created SSH certificate.
+- `key_id` - (optional) The key ID for the created SSH certificate. You can create a template for this value using [Vault credential library parameter templating](#vault-certificates-library-parameter-templating).
- `critical_options` - (optional) Any critical options that the certificate should be signed for.
For more information, refer to the [list of critical options](https://github.com/openssh/openssh-portable/blob/5f93c4836527d9fda05de8944a1c7b4a205080c7/PROTOCOL.certkeys#L221-L269) supported by OpenSSH.
@@ -86,11 +86,13 @@ Note that the `permit-pty` value should be set for an interactive shell to funct
For more information, refer to OpenSSH's ["valid principals" definition](https://github.com/openssh/openssh-portable/blob/5f93c4836527d9fda05de8944a1c7b4a205080c7/PROTOCOL.certkeys#L176-L181) as well as Vault's documentation for the [SSH secrets engine](https://developer.hashicorp.com/vault/api-docs/secret/ssh#valid_principals).
Note that all SSH certificates issued by a Vault SSH certificate credential library use the `SSH_CERT_TYPE_USER` certificate type mentioned in the OpenSSH definition link.
-### Vault credential library parameter templating
+### Vault parameter templating
Sometimes it can be useful to provide information about a Boundary user or account when making a call to Vault. For example, this can allow picking the correct role when asking for database credentials (if roles are separated per-user), or providing a value to encode in an X.509 certificate generated by Vault. You can template user and account information into either the path in Vault, the `POST` request body, or both.
-The following Vault template parameters are supported in Boundary.
+#### Vault generic credential library parameter templating
+
+The following Vault template parameters are supported in Boundary's Vault generic credential library.
Note that account values are tied to the account associated with the token used to make the call:
- `{{.User.Id}}` - The user's ID.
@@ -105,7 +107,15 @@ This value may not be populated, or it may be different from the account name us
- `{{.Account.Subject}}` - The account's subject, if a subject is used by that type of account.
- `{{.Account.Email}}` - The account's email, if email is used by that type of account.
-Additionally, there are a couple of useful functions:
+#### Vault certificates library parameter templating
+
+The following Vault template parameters are supported in Boundary's Vault certificate library.
+Note that account values are tied to the account associated with the token used to make the call:
+
+- `{{.User.Name}}` - The user's name from the user resource.
+- `{{.Account.Id}}` - The account's ID.
+
+#### Useful templating functions:
The `truncateFrom` function strips the rest of a string after a specified
substring. This function is useful for pulling a user or account name from an
diff --git a/website/content/docs/domain-model/credential-stores.mdx b/website/content/docs/domain-model/credential-stores.mdx
index 6b6538d190..38968f910f 100644
--- a/website/content/docs/domain-model/credential-stores.mdx
+++ b/website/content/docs/domain-model/credential-stores.mdx
@@ -122,8 +122,7 @@ removed from the credential store.
#### Vault Boundary controller policy
-The token Boundary receives must have the capabilities listed below. An explanation
-for the use of each capability is given.
+The token Boundary receives must have the capabilities in the policy below. An explanation for each capability is documented above the written policy.
```hcl
# Allow Boundary to read and verify the properties of the token. This is
@@ -165,14 +164,41 @@ path "sys/capabilities-self" {
}
```
-The above [`boundary-controller` policy](https://boundaryproject.io/data/vault/boundary-controller-policy.hcl) is
-available for download. Below is an example of writing this policy to Vault:
+Follow the steps below to write this policy to Vault.
+
+Create the policy:
```shell-session
-# Download the policy
-$ curl https://boundaryproject.io/data/vault/boundary-controller-policy.hcl -O -s -L
+$ cat > boundary-controller-policy.hcl <