Created
June 5, 2020 19:55
-
-
Save zalary/8afec9255e0da3da3c888b3de4acbcbf to your computer and use it in GitHub Desktop.
cannot list policies when control group is set for read/update operations
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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