Skip to content

Instantly share code, notes, and snippets.

@zalary
Created June 5, 2020 19:55
Show Gist options
  • Save zalary/8afec9255e0da3da3c888b3de4acbcbf to your computer and use it in GitHub Desktop.
Save zalary/8afec9255e0da3da3c888b3de4acbcbf to your computer and use it in GitHub Desktop.
cannot list policies when control group is set for read/update operations
#!/bin/bash
set -aex
ps aux | grep "vault server" | grep -v grep | awk '{print $2}' | xargs kill
sleep 2s
tee /tmp/config.hcl <<EOF
storage "inmem" {}
ui = true
listener "tcp" {
address = "127.0.0.1:8200"
tls_disable = "true"
}
api_addr = "http://127.0.0.1:8200"
pid_file = "/tmp/vault.pid"
EOF
vault server -log-level=trace -config /tmp/config.hcl > /tmp/config.log 2>&1 &
while ! nc -w 1 localhost 8200 </dev/null; do sleep 1; done
initResponse=$(vault operator init -format=json -key-shares 1 -key-threshold 1)
unsealKey=$(echo $initResponse | jq -r '.unseal_keys_b64[0]')
rootToken=$(echo $initResponse| jq -r '.root_token')
vault operator unseal $unsealKey
sleep 3s
####
#
# Setup:
# - Auth: userpass. Setup should work with other auth methods as well
# - Requestor: "nsadmin" which lives in the root namespace
# - Approver: "approver" which lives in the root namespace
# - Group: "approvers" which lives in the root namespace, with "approver" as the member
#
####
vault login $rootToken
# Create namespace
vault namespace create team1
# Enable userpass
vault auth enable userpass
# Set up nsapprover policy and user. This needs to happen
# first since the admin policy needs to contain the group ID
# that the approver is on.
cat > /tmp/nsapprover.hcl -<<EOF
# To approve the request
path "team1/sys/control-group/authorize" {
capabilities = ["create", "update"]
}
# To check control group request status
path "team1/sys/control-group/request" {
capabilities = ["create", "update"]
}
EOF
vault policy write nsapprover /tmp/nsapprover.hcl
vault write auth/userpass/users/approver password=bar policies=nsapprover
# Set up entity group
nsApproverToken=$(vault write -format json auth/userpass/login/approver password=bar | jq -r '.auth.client_token')
nsApproverEntityID=$(VAULT_TOKEN=$nsApproverToken vault token lookup -format json | jq -r '.data.entity_id')
vault write -format json identity/group name=approvers member_entity_ids=$nsApproverEntityID
groupID=$(vault read -format json identity/group/name/approvers | jq -r '.data .id')
# Set up nsadmin policy and user
cat > /tmp/nsadmin.hcl -<<EOF
# Default to granting full access to the namespace
path "team1/*" {
capabilities = [
"create", "read", "update", "delete", "list", "sudo"
]
}
# Limit creation of new policies to those approved by Infra
path "team1/sys/policy/*" {
capabilities = ["delete", "list", "read"]
}
path "team1/sys/policies/acl/*" {
capabilities = ["delete", "list", "read"]
}
# Annoyingly writing a new policy requires updated permission rather than create permission
# so we cannot differentiate between the two actions here
path "team1/sys/policy/*" {
capabilities = ["create", "update"]
control_group = {
ttl = "168h"
factor "infra approval" {
identity {
group_ids = ["$groupID"]
approvals = 1
}
}
}
}
path "team1/sys/policies/acl/*" {
capabilities = ["create", "update"]
control_group = {
ttl = "168h"
factor "infra approval" {
identity {
group_ids = ["$groupID"]
approvals = 1
}
}
}
}
EOF
vault policy write nsadmin /tmp/nsadmin.hcl
vault write auth/userpass/users/admin password=bar policies=nsadmin
# Generate an nsadmin token
nsAdminToken=$(vault write -format json auth/userpass/login/admin password=bar | jq -r '.auth.client_token')
# Dummy policy for nsadmin to use and trigger the CG flow
cat > /tmp/test-policy.hcl <<EOF
path "foo/bar/*" {
capabilities = ["create", "update"]
}
EOF
# Issue a policy creation request from admin. Should be blocked by CG approval
wrappedResponse=$(VAULT_TOKEN=$nsAdminToken vault write -ns team1 -format json sys/policy/xname02 policy=@/tmp/test-policy.hcl)
wrappedAccessor=$(echo -n $wrappedResponse | jq -r '.wrap_info.accessor')
wrappedToken=$(echo -n $wrappedResponse | jq -r '.wrap_info.token')
# Issue an approval
VAULT_TOKEN=$nsApproverToken vault write team1/sys/control-group/request accessor=$wrappedAccessor
VAULT_TOKEN=$nsApproverToken vault write team1/sys/control-group/authorize accessor=$wrappedAccessor
# Look at authorized request
VAULT_TOKEN=$nsApproverToken vault write team1/sys/control-group/request accessor=$wrappedAccessor
# Unwrap the token to process the request
VAULT_TOKEN=$nsAdminToken vault unwrap $wrappedToken
# List the policy in team1 namespace, should contain "xname02"
VAULT_TOKEN=$rootToken vault policy list -ns team1
VAULT_TOKEN=$nsAdminToken vault policy list -ns team1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment