Create vault policies recoinciling script
This commit is contained in:
@@ -22,6 +22,9 @@
|
|||||||
in
|
in
|
||||||
pkgs.mkShell {
|
pkgs.mkShell {
|
||||||
packages = with pkgs; [
|
packages = with pkgs; [
|
||||||
|
(python313.withPackages (python-pkgs: with python-pkgs; [
|
||||||
|
hvac
|
||||||
|
]))
|
||||||
vim gnumake
|
vim gnumake
|
||||||
talosctl cilium-cli
|
talosctl cilium-cli
|
||||||
kubectx k9s kubernetes-helm
|
kubectx k9s kubernetes-helm
|
||||||
@@ -47,6 +50,9 @@
|
|||||||
# export AWS_SECRET_ACCESS_KEY=?
|
# export AWS_SECRET_ACCESS_KEY=?
|
||||||
# export RESTIC_PASSWORD=?
|
# export RESTIC_PASSWORD=?
|
||||||
export VAULT_ADDR=https://openbao.lumpiasty.xyz:8200
|
export VAULT_ADDR=https://openbao.lumpiasty.xyz:8200
|
||||||
|
|
||||||
|
# Add scripts from utils subdir
|
||||||
|
export PATH="$PATH:$(pwd)/utils"
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
75
utils/synchronize-vault.py
Executable file
75
utils/synchronize-vault.py
Executable file
@@ -0,0 +1,75 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
from hvac.api.system_backend import mount
|
||||||
|
import yaml
|
||||||
|
import hvac
|
||||||
|
from hvac.api.auth_methods import Kubernetes, kubernetes
|
||||||
|
|
||||||
|
# Read vault/policies dir then write what is there and delete missing
|
||||||
|
def synchronize_policies(client: hvac.Client):
|
||||||
|
policies = {}
|
||||||
|
# Read all policies files
|
||||||
|
policy_dir = os.path.join(os.path.dirname(__file__), '../vault/policy')
|
||||||
|
for filename in os.listdir(policy_dir):
|
||||||
|
with open(os.path.join(policy_dir, filename), 'r') as f:
|
||||||
|
policy_name = os.path.splitext(filename)[0]
|
||||||
|
policies[policy_name] = f.read()
|
||||||
|
|
||||||
|
policies_on_vault = client.sys.list_policies()['data']['policies']
|
||||||
|
|
||||||
|
# Delete policies that should not be there
|
||||||
|
for policy in policies_on_vault:
|
||||||
|
if policy not in policies and policy != 'root':
|
||||||
|
print(f'Deleting policy: {policy}')
|
||||||
|
client.sys.delete_policy(policy)
|
||||||
|
|
||||||
|
# Update policies from local directory
|
||||||
|
for policy_name, policy_content in policies.items():
|
||||||
|
print(f'Updating policy: {policy_name}')
|
||||||
|
client.sys.create_or_update_acl_policy(policy_name, policy_content)
|
||||||
|
|
||||||
|
# Read vault/kubernetes-roles dir then write what is there and delete missing
|
||||||
|
def synchronize_kubernetes_roles(client: hvac.Client):
|
||||||
|
kubernetes = Kubernetes(client.adapter)
|
||||||
|
|
||||||
|
policy_dir = os.path.join(os.path.dirname(__file__), '../vault/kubernetes-roles/')
|
||||||
|
|
||||||
|
roles = {}
|
||||||
|
for filename in os.listdir(policy_dir):
|
||||||
|
with open(os.path.join(policy_dir, filename), 'r') as f:
|
||||||
|
role_name = os.path.splitext(filename)[0]
|
||||||
|
roles[role_name] = yaml.safe_load(f.read())
|
||||||
|
|
||||||
|
roles_on_vault = []
|
||||||
|
try:
|
||||||
|
roles_on_vault = kubernetes.list_roles()['keys']
|
||||||
|
except hvac.exceptions.InvalidPath:
|
||||||
|
print("No roles found on server!")
|
||||||
|
|
||||||
|
|
||||||
|
for role in roles_on_vault:
|
||||||
|
if role not in roles_on_vault:
|
||||||
|
print(f'Deleting role: {role}')
|
||||||
|
kubernetes.delete_role(role)
|
||||||
|
|
||||||
|
for role_name, role_content in roles.items():
|
||||||
|
print(f'Updating role: {role_name}')
|
||||||
|
# Using write data instead of kubernetes.create_role, we can pass raw yaml
|
||||||
|
client.write_data(f'/auth/kubernetes/role/{role_name}', data=role_content)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
prog="synchronizeVault",
|
||||||
|
description="Update vault config"
|
||||||
|
)
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
client = hvac.Client(url=os.environ['VAULT_ADDR'])
|
||||||
|
|
||||||
|
print('Synchronizing policies')
|
||||||
|
synchronize_policies(client)
|
||||||
|
|
||||||
|
print('Synchronizing kubernetes roles')
|
||||||
|
synchronize_kubernetes_roles(client)
|
||||||
86
vault/policy/default.hcl
Normal file
86
vault/policy/default.hcl
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
# Allow tokens to look up their own properties
|
||||||
|
path "auth/token/lookup-self" {
|
||||||
|
capabilities = ["read"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Allow tokens to renew themselves
|
||||||
|
path "auth/token/renew-self" {
|
||||||
|
capabilities = ["update"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Allow tokens to revoke themselves
|
||||||
|
path "auth/token/revoke-self" {
|
||||||
|
capabilities = ["update"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Allow a token to look up its own capabilities on a path
|
||||||
|
path "sys/capabilities-self" {
|
||||||
|
capabilities = ["update"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Allow a token to look up its own entity by id or name
|
||||||
|
path "identity/entity/id/{{identity.entity.id}}" {
|
||||||
|
capabilities = ["read"]
|
||||||
|
}
|
||||||
|
path "identity/entity/name/{{identity.entity.name}}" {
|
||||||
|
capabilities = ["read"]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Allow a token to look up its resultant ACL from all policies. This is useful
|
||||||
|
# for UIs. It is an internal path because the format may change at any time
|
||||||
|
# based on how the internal ACL features and capabilities change.
|
||||||
|
path "sys/internal/ui/resultant-acl" {
|
||||||
|
capabilities = ["read"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Allow a token to renew a lease via lease_id in the request body; old path for
|
||||||
|
# old clients, new path for newer
|
||||||
|
path "sys/renew" {
|
||||||
|
capabilities = ["update"]
|
||||||
|
}
|
||||||
|
path "sys/leases/renew" {
|
||||||
|
capabilities = ["update"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Allow looking up lease properties. This requires knowing the lease ID ahead
|
||||||
|
# of time and does not divulge any sensitive information.
|
||||||
|
path "sys/leases/lookup" {
|
||||||
|
capabilities = ["update"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Allow a token to manage its own cubbyhole
|
||||||
|
path "cubbyhole/*" {
|
||||||
|
capabilities = ["create", "read", "update", "delete", "list"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Allow a token to wrap arbitrary values in a response-wrapping token
|
||||||
|
path "sys/wrapping/wrap" {
|
||||||
|
capabilities = ["update"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Allow a token to look up the creation time and TTL of a given
|
||||||
|
# response-wrapping token
|
||||||
|
path "sys/wrapping/lookup" {
|
||||||
|
capabilities = ["update"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Allow a token to unwrap a response-wrapping token. This is a convenience to
|
||||||
|
# avoid client token swapping since this is also part of the response wrapping
|
||||||
|
# policy.
|
||||||
|
path "sys/wrapping/unwrap" {
|
||||||
|
capabilities = ["update"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Allow general purpose tools
|
||||||
|
path "sys/tools/hash" {
|
||||||
|
capabilities = ["update"]
|
||||||
|
}
|
||||||
|
path "sys/tools/hash/*" {
|
||||||
|
capabilities = ["update"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Allow a token to make requests to the Authorization Endpoint for OIDC providers.
|
||||||
|
path "identity/oidc/provider/+/authorize" {
|
||||||
|
capabilities = ["read", "update"]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user