Installing Boundary Without Generated Resources

What are generated resources? When you run boundary dev or boundary database init, Boundary automatically generates a number of resources to make getting started easier. Default scopes, auth methods, user, account, and targets are just some of the resources Boundary will generate unless you tell it not to.

In a production or long-running environment, these resources are not necessary, but without them, managing Boundary from scratch isn’t straight forward. How do you create your first user and login to administer a Boundary deployment that has no authentication methods, users, accounts, etc.? This section describes how to get your freshly deployed Boundary installation off the ground for non-dev environments.

Recovery KMS Workflow

Initializing Boundary without generated resources starts with your Boundary configuration file. Specifically, the controller configuration specifies three KMS blocks:

  1. <truncated>
  2. kms "aead" {
  3. purpose = "root"
  4. aead_type = "aes-gcm"
  5. key = "sP1fnF5Xz85RrXyELHFeZg9Ad2qt4Z4bgNHVGtD6ung="
  6. key_id = "global_root"
  7. }
  8. kms "aead" {
  9. purpose = "worker-auth"
  10. aead_type = "aes-gcm"
  11. key = "8fZBjCUfN0TzjEGLQldGY4+iE9AkOvCfjh7+p0GtRBQ="
  12. key_id = "global_worker-auth"
  13. }
  14. kms "aead" {
  15. purpose = "recovery"
  16. aead_type = "aes-gcm"
  17. key = "8fZBjCUfN0TzjEGLQldGY4+iE9AkOvCfjh7+p0GtRBQ="
  18. key_id = "global_recovery"
  19. }
  20. <truncated>
  1. <truncated>kms "aead" { purpose = "root" aead_type = "aes-gcm" key = "sP1fnF5Xz85RrXyELHFeZg9Ad2qt4Z4bgNHVGtD6ung=" key_id = "global_root"}
  2. kms "aead" { purpose = "worker-auth" aead_type = "aes-gcm" key = "8fZBjCUfN0TzjEGLQldGY4+iE9AkOvCfjh7+p0GtRBQ=" key_id = "global_worker-auth"}
  3. kms "aead" { purpose = "recovery" aead_type = "aes-gcm" key = "8fZBjCUfN0TzjEGLQldGY4+iE9AkOvCfjh7+p0GtRBQ=" key_id = "global_recovery"}<truncated>

In this example, we’re using hardcoded AEAD keys, but in a real world non-dev deployment, you should use your cloud provider’s KMS such as AWS KMS to manage the keys Boundary uses to encrypt sensitive information.

The KMS block we’re focused on is the recovery block. This block specifies the key used to “recover” Boundary but you can also use it to authenticate to Boundary and manage it as a “global” super user. This allows you to authenticate from the CLI or from Terraform in order to manage Boundary without any generated resources.

To authenticate to Boundary using the recovery KMS workflow:

CLITerraform

To use the recovery workflow on the CLI, you must pass the -recovery-config <path_to_kms_recovery_config> flag or set the environment variable for BOUNDARY_RECOVERY_CONFIG for every command ran. Authentication takes place for every command ran when using the recovery workflow, there is no boundary authenticate step:

  1. $ cat << EOF > /tmp/recovery.hcl
  2. kms "aead" {
  3. purpose = "recovery"
  4. aead_type = "aes-gcm"
  5. key = "8fZBjCUfN0TzjEGLQldGY4+iE9AkOvCfjh7+p0GtRBQ="
  6. key_id = "global_recovery"
  7. }
  8. EOF
  9. $ boundary users create <truncated> -recovery-config /tmp/recovery.hcl
  10. ...
  1. $ cat << EOF > /tmp/recovery.hclkms "aead" { purpose = "recovery" aead_type = "aes-gcm" key = "8fZBjCUfN0TzjEGLQldGY4+iE9AkOvCfjh7+p0GtRBQ=" key_id = "global_recovery"}EOF
  2. $ boundary users create <truncated> -recovery-config /tmp/recovery.hcl...

Initialize the Database

Before you can start Boundary, the database must be initialized. It’s useful to look at the help output for the init command:

  1. $ boundary database init -h
  2. ...
  1. $ boundary database init -h...

From this command, you can see the flags available to skip the creation of auto-generated resources.

To initialize the Boundary database without generated resources:

  1. $ boundary database init \
  2. -skip-auth-method-creation \
  3. -skip-host-resources-creation \
  4. -skip-scopes-creation \
  5. -skip-target-creation \
  6. -config /etc/boundary.hcl
  1. $ boundary database init \ -skip-auth-method-creation \ -skip-host-resources-creation \ -skip-scopes-creation \ -skip-target-creation \ -config /etc/boundary.hcl

When you start Boundary, you will effectively have a blank sheet to work against. The initial migrations in the database have been run (note that this includes creating special users like u_anon and the global scope) and the internal keyrings have been initialized. From here, it’s required that you use the KMS recovery workflow described above to create at a minimum an auth method, a user, an account, and a role with sufficient grants. Otherwise, you need to continue to use the recovery workflow for management. It’s important to realize that this is effectively a global super user type of workflow and comes with security concerns.

Creating Your First Login Account

This section covers how to configure your first auth method, user, account, and role to login to Boundary without the recovery KMS workflow. In this example, we’re going to make an admin user for the global and project level scopes we create. This will allow our user to configure targets within those scopes and manage them.

Create Org and Project Scopes

In this example, we’re going to create an org and project scope and skip creating an administrator and admin role for each scope. We’re going to specify a role for managing these scopes by selected users in a later step.

CLITerraform

  1. $ boundary scopes create -name 'org' -scope-id 'global' \
  2. -recovery-config /tmp/recovery.hcl \
  3. -skip-admin-role-creation \
  4. -skip-default-role-creation
  5. <truncated>
  6. $ boundary scopes create -name 'project' -scope-id <org_scope_id_from_last_step> \
  7. -recovery-config /tmp/recovery.hcl \
  8. -skip-admin-role-creation \
  9. -skip-default-role-creation
  10. <truncated>
  1. $ boundary scopes create -name 'org' -scope-id 'global' \ -recovery-config /tmp/recovery.hcl \ -skip-admin-role-creation \ -skip-default-role-creation<truncated>
  2. $ boundary scopes create -name 'project' -scope-id <org_scope_id_from_last_step> \ -recovery-config /tmp/recovery.hcl \ -skip-admin-role-creation \ -skip-default-role-creation<truncated>

Create an Auth Method

Create an auth method in the organization scope.

CLITerraform

  1. $ boundary auth-methods create password \
  2. -recovery-config /tmp/recovery.hcl \
  3. -scope-id <org_scope_id> \
  4. -name 'my_method' \
  5. -description 'My password auth method'
  1. $ boundary auth-methods create password \ -recovery-config /tmp/recovery.hcl \ -scope-id <org_scope_id> \ -name 'my_method' \ -description 'My password auth method'

Create a Login Account

Create a login account for the auth method.

CLITerraform

  1. $ boundary accounts create password \
  2. -recovery-config /tmp/recovery.hcl \
  3. -login-name "myuser" \
  4. -password "foofoofoo" \
  5. -auth-method-id <auth_method_id_from_last_step>
  1. $ boundary accounts create password \ -recovery-config /tmp/recovery.hcl \ -login-name "myuser" \ -password "foofoofoo" \ -auth-method-id <auth_method_id_from_last_step>

Create a User

Create a user and associate the user with the login account created in the previous step. This user will also be the principal in the role we create in the following step.

CLITerraform

  1. $ boundary users create -scope-id <org_scope_id> \
  2. -recovery-config /tmp/recovery.hcl \
  3. -name "myuser" \
  4. -description "My user!"
  5. $ boundary users add-accounts \
  6. -recovery-config /tmp/recovery.hcl \
  7. -id <myuser_user_id> \
  8. -account <myuser_account_id>
  1. $ boundary users create -scope-id <org_scope_id> \ -recovery-config /tmp/recovery.hcl \ -name "myuser" \ -description "My user!"
  2. $ boundary users add-accounts \ -recovery-config /tmp/recovery.hcl \ -id <myuser_user_id> \ -account <myuser_account_id>

Create Roles to Manage Scopes

The following describes the four baseline roles you’ll need to create to manage resources within the org and project scopes created above. These roles are similar to the roles created for you if generation had not been skipped during boundary database init when executed with the -skip-initial-login-role-creation flag, Declaring roles explicitly allows you to manage them independently and fully within Terraform or via the CLI. In doing so, you can precisely define their access.

The following example creates 4 roles:

  1. To allow anonymous (unauthenticated) users the ability to list scopes and auth methods in the global scope.
  2. To allow anonymous (unauthenticated) users the ability to list scopes and auth methods in the organization scope.
  3. To allow myuser user administration grants at the org scope.
  4. To allow myuser user administration grants at the project scope.

Anonymous listing role for global scope

CLITerraform

Assumes recovery key export from above steps is still set:

  1. # Create global anonymous listing role
  2. $ boundary roles create -name 'global_anon_listing' \
  3. -recovery-config /tmp/recovery.hcl \
  4. -scope-id 'global'
  5. $ boundary roles add-grants -id <global_anon_listing_id> \
  6. -recovery-config /tmp/recovery.hcl \
  7. -grant 'id=*;type=auth-method;actions=list,authenticate' \
  8. -grant 'id=*;type=scope;actions=list,no-op' \
  9. -grant 'id={{account.id}};actions=read,change-password'
  10. $ boundary roles add-principals -id <global_anon_listing_id> \
  11. -recovery-config /tmp/recovery.hcl \
  12. -principal 'u_anon'
  1. # Create global anonymous listing role$ boundary roles create -name 'global_anon_listing' \ -recovery-config /tmp/recovery.hcl \ -scope-id 'global'
  2. $ boundary roles add-grants -id <global_anon_listing_id> \ -recovery-config /tmp/recovery.hcl \ -grant 'id=*;type=auth-method;actions=list,authenticate' \ -grant 'id=*;type=scope;actions=list,no-op' \ -grant 'id={{account.id}};actions=read,change-password'
  3. $ boundary roles add-principals -id <global_anon_listing_id> \ -recovery-config /tmp/recovery.hcl \ -principal 'u_anon'

Anonymous listing role for org scope

CLITerraform

Assumes recovery key export from above steps is still set:

  1. $ boundary roles create -name 'org_anon_listing' \
  2. -recovery-config /tmp/recovery.hcl \
  3. -scope-id <org_scope_id>
  4. $ boundary roles add-grants -id <org_anon_listing_id> \
  5. -recovery-config /tmp/recovery.hcl \
  6. -grant 'id=*;type=auth-method;actions=list,authenticate' \
  7. -grant 'type=scope;actions=list' \
  8. -grant 'id={{account.id}};actions=read,change-password'
  9. $ boundary roles add-principals -id <org_anon_listing_id> \
  10. -recovery-config /tmp/recovery.hcl \
  11. -principal 'u_anon'
  1. $ boundary roles create -name 'org_anon_listing' \ -recovery-config /tmp/recovery.hcl \ -scope-id <org_scope_id>
  2. $ boundary roles add-grants -id <org_anon_listing_id> \ -recovery-config /tmp/recovery.hcl \ -grant 'id=*;type=auth-method;actions=list,authenticate' \ -grant 'type=scope;actions=list' \ -grant 'id={{account.id}};actions=read,change-password'
  3. $ boundary roles add-principals -id <org_anon_listing_id> \ -recovery-config /tmp/recovery.hcl \ -principal 'u_anon'

Org admin role for myuser

CLITerraform

Assumes recovery key export from above steps is still set:

  1. $ boundary roles create -name 'org_admin' \
  2. -recovery-config /tmp/recovery.hcl \
  3. -scope-id 'global' \
  4. -grant-scope-id <org_scope_id>
  5. $ boundary roles add-grants -id <org_admin_id> \
  6. -recovery-config /tmp/recovery.hcl \
  7. -grant 'id=*;type=*;actions=*'
  8. $ boundary roles add-principals -id <org_admin_id> \
  9. -recovery-config /tmp/recovery.hcl \
  10. -principal <myuser_user_id>
  1. $ boundary roles create -name 'org_admin' \ -recovery-config /tmp/recovery.hcl \ -scope-id 'global' \ -grant-scope-id <org_scope_id>
  2. $ boundary roles add-grants -id <org_admin_id> \ -recovery-config /tmp/recovery.hcl \ -grant 'id=*;type=*;actions=*'
  3. $ boundary roles add-principals -id <org_admin_id> \ -recovery-config /tmp/recovery.hcl \ -principal <myuser_user_id>

Project admin for myuser

CLITerraform

Assumes recovery key export from above steps is still set:

  1. $ boundary roles create -name 'project_admin' \
  2. -recovery-config /tmp/recovery.hcl \
  3. -scope-id <org_scope_id> \
  4. -grant-scope-id <project_scope_id>
  5. $ boundary roles add-grants -id <project_admin_id> \
  6. -recovery-config /tmp/recovery.hcl \
  7. -grant 'id=*;type=*;actions=*'
  8. $ boundary roles add-principals -id <project_admin_id> \
  9. -recovery-config /tmp/recovery.hcl \
  10. -principal <myuser_user_id>
  1. $ boundary roles create -name 'project_admin' \ -recovery-config /tmp/recovery.hcl \ -scope-id <org_scope_id> \ -grant-scope-id <project_scope_id>
  2. $ boundary roles add-grants -id <project_admin_id> \ -recovery-config /tmp/recovery.hcl \ -grant 'id=*;type=*;actions=*'
  3. $ boundary roles add-principals -id <project_admin_id> \ -recovery-config /tmp/recovery.hcl \ -principal <myuser_user_id>

Login as Your New User

  1. boundary authenticate password \
  2. -auth-method-id <auth_method_id> \
  3. -login-name myuser \
  4. -password foofoofoo
  1. boundary authenticate password \ -auth-method-id <auth_method_id> \ -login-name myuser \ -password foofoofoo