Namespaces are available only in Stronghold EE.

A namespace works as a separate virtual Stronghold with its own secrets engines, auth methods, policies, and tokens. A team gets a namespace, and its administrators manage it on their own without access to the root namespace or to other teams’ namespaces.

Goal

Create a namespace for the team-a team, grant its administrators delegated permissions, set up separate auth methods for people and applications, and configure templated policies that do not need changes when new applications are added.

Prerequisites

To follow this example, you need:

  • Stronghold EE.
  • A root namespace administrator token.
  • OIDC client parameters in the IdP for the team (address, client_id, client_secret) if people log in through OIDC.
  • The team’s Kubernetes cluster if applications authenticate with the Kubernetes method.

Step 1. Create a namespace

Log in with the root namespace administrator token and create the team-a namespace:

d8 stronghold namespace create -custom-metadata=owner="team-a@example.com" team-a

The commands below are run in this namespace and pass the -namespace=team-a flag explicitly.

Step 2. Create a delegated administrator policy

Paths in the policy are relative to the namespace. The policy allows managing secrets engines, auth methods, policies, and Identity inside team-a, but grants no permissions outside it:

d8 stronghold policy write -namespace=team-a team-admin - <<'POLICY'
# Managing secrets engines and auth methods.
path "sys/mounts/*" {
  capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}
path "sys/mounts" {
  capabilities = ["read"]
}
path "sys/auth/*" {
  capabilities = ["create", "read", "update", "delete", "sudo"]
}
path "sys/auth" {
  capabilities = ["read"]
}

# Managing policies.
path "sys/policies/acl/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

# Configuring auth methods and Identity.
path "auth/*" {
  capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}
path "identity/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

# Working with team secrets.
path "secret/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

# Nested namespaces.
path "sys/namespaces/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}
POLICY

Remove blocks the team must not control, for example sys/namespaces/*.

Step 3. Set up an auth method for people

Set up OIDC login for the team administrators:

  1. Enable OIDC in the team namespace:

    d8 stronghold auth enable -namespace=team-a oidc
  2. Configure the method and a role as described in OIDC auth method, passing -namespace=team-a to each command. In the role, set the claim with user groups (groups_claim).

  3. Bind the team-admin policy to the team’s administrator group in the IdP:

    OIDC_ACCESSOR=$(d8 stronghold read -namespace=team-a -field=accessor sys/auth/oidc)
    
    GROUP_ID=$(d8 stronghold write -namespace=team-a -field=id identity/group name=team-a-admins type=external policies=team-admin)
    
    d8 stronghold write -namespace=team-a identity/group-alias name=team-a-admins mount_accessor="$OIDC_ACCESSOR" canonical_id="$GROUP_ID"

From now on, team administrators log in with d8 stronghold login -namespace=team-a -method=oidc and continue without the root namespace administrator.

Step 4. Set up an auth method for applications

Set up the Kubernetes auth method and a KV store for the team’s applications:

  1. Enable the Kubernetes method for the team’s cluster:

    d8 stronghold auth enable -namespace=team-a kubernetes
    d8 stronghold write -namespace=team-a auth/kubernetes/config kubernetes_host="https://<API_SERVER_ADDRESS>:6443" kubernetes_ca_cert=@ca.crt

    <API_SERVER_ADDRESS> is the address of the Kubernetes API server of the team’s cluster. The ca.crt file contains its CA certificate.

    Configuration parameters are described in Kubernetes auth method.

  2. Enable the team’s KV store:

    d8 stronghold secrets enable -namespace=team-a -path=secret -version=2 kv

Step 5. Configure a templated policy for applications

Instead of a separate policy for each application, use one templated policy: an application gets access to secrets in the directory that matches its Kubernetes namespace.

K8S_ACCESSOR=$(d8 stronghold read -namespace=team-a -field=accessor sys/auth/kubernetes)

d8 stronghold policy write -namespace=team-a app-by-namespace - <<POLICY
path "secret/data/{{identity.entity.aliases.${K8S_ACCESSOR}.metadata.service_account_namespace}}/*" {
  capabilities = ["read"]
}
POLICY

d8 stronghold write -namespace=team-a auth/kubernetes/role/apps bound_service_account_names="*" bound_service_account_namespaces="team-a-*" policies=app-by-namespace ttl=1h

bound_service_account_namespaces also accepts patterns with a trailing * (for example, team-a-*).

An application from the team-a-billing Kubernetes namespace can read secret/data/team-a-billing/*, but not the team-a-orders secrets.

In the same way, you can give each employee a personal directory:

d8 stronghold policy write -namespace=team-a personal - <<'POLICY'
path "secret/data/users/{{identity.entity.id}}/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}
path "secret/metadata/users/{{identity.entity.id}}/*" {
  capabilities = ["read", "list", "delete"]
}
POLICY

Verification

Check the result:

  1. Log in as a team administrator and check that management inside the namespace is available:

    d8 stronghold login -namespace=team-a -method=oidc
    d8 stronghold secrets list -namespace=team-a
  2. Check that access to the root namespace is denied. The command runs without -namespace, so the request goes to the root namespace. The command must return a permission denied error:

    d8 stronghold secrets list
  3. Compare token capabilities on paths of different teams:

    d8 stronghold token capabilities -namespace=team-a secret/data/team-a-billing/db

Cleanup

Deleting a namespace deletes all its secrets engines, auth methods, policies, and tokens. The team administrator token cannot delete the namespace. Log in with the root namespace administrator token and delete the namespace:

d8 stronghold login
d8 stronghold namespace delete team-a

Before deleting a production namespace, take a storage snapshot.

Additional resources