Skip to main content

Recommended Blueprint

Cordial Scripting Language is a minimal language that can be used to initialize all of the policies, users, and credentials on your install. Learn more in the tutorial.

This CSL "blueprint" can be applied after a fresh Treasury install. It configures a basic set of rules and approval requirements for sensitive operations. It also creates accounts admin-1 with invite code 61646d696e2d31 (the hex value corresponding to the string "admin-1"), and admin-2 with invite code 61646d696e2d32 (the hex value corresponding to the string "admin-2").

Edit as necessary.

treasury script -f blueprint.csl

Blueprint

blueprint.csl
# start with root invite
_, err = create invite client key root-invite { code = hex("root") }
root-invite = client key root-invite
set sign.with = root-invite

# root key
_, err = create k256 client key root-key
root-key = client key root-key

create k256 credential for root { public_key = $root-key.public_key }

set sign.with = root-key

# template roles for users
create role super-admin { user = "human" }
create role admin { user = "human", credential = ["k256", "web-authn", "session"] }
create role operator { user = "human", credential = ["web-authn", "session"] }
create role programmatic-transfer { user = "machine", credential = "k256" }

# required roles for connector + signer to function
create role connector { user = "machine", credential = "k256" }
create role signer { user = "machine", credential = "k256" }

# allow example roles to collaborate on appropriate resources
create allow access-rule super-admin { action = "any/action", resource = "any/resource", initiate = "roles/super-admin", approvals = 1 }
create allow access-rule admin { action = "any/action", resource = ["AccessRule", "Credential", "Feature", "Role", "SoftwareUpdate", "User"], initiate = "roles/admin", approvals = 1 }
create allow access-rule operator-approve { action = "any/action", resource = ["Account", "Address", "Asset", "Chain", "Symbol", "TransferRule"], initiate = "roles/operator", approvals = 1 }

# permit root user to approve any admin action with 1 approval
create allow access-rule root-approve { action = "any/action", resource = "any/resource", initiate = ["roles/admin", "roles/super-admin"], approve = "users/root", approvals = 1 }

create allow access-rule transfers { action = "any/action", resource = "Transfer", initiate = ["roles/operator", "roles/programmatic-transfer"] }
create allow access-rule stakings { action = "any/action", resource = "Staking", initiate = ["roles/operator", "roles/programmatic-transfer"] }
create allow access-rule internal-address { action = "create", resource = { type = "Address", variant = "internal" }, initiate = "roles/operator" }
create allow access-rule delete-allow-rule { action = "delete", resource = { type = "TransferRule", variant = "allow" }, initiate = "roles/operator" }
create allow access-rule create-deny-rule { action = "create", resource = { type = "TransferRule", variant = "deny" }, initiate = "roles/operator" }
create allow access-rule create-require-rule { action = "create", resource = { type = "TransferRule", variant = "require" }, initiate = "roles/operator" }
create allow access-rule create-credential { action = "create", resource = {type = "Credential", variant = ["k256", "web-authn", "web-authn-uv", "session", "ed255", "p256"]}, initiate = "any/user" }

# for connector + signer treasury processes
create allow access-rule connector-transactions { action = "any/action", resource = "Transaction", initiate = "roles/connector" }
create allow access-rule connector-prices { action = "custom/price", resource = "Asset", initiate = "roles/connector" }
create allow access-rule signer-responses { action = "any/action", resource = ["KeyResponse", "SignatureResponse"], initiate = "roles/signer" }
create allow access-rule service-heartbeats { action = "custom/heartbeat", resource = "User", initiate = "any/user" }

# add 2 admin users to bootstrap
create human user admin-1 { roles = ["roles/admin", "roles/super-admin"] }
create invite credential for admin-1 { public_key = invite-public(hex("admin-1")) }

create human user admin-2 { roles = ["roles/admin", "roles/super-admin"] }
create invite credential for admin-2 { public_key = invite-public(hex("admin-2")) }

# create user account for connector(s)
create machine user connector-1 { roles = ["roles/connector"] }
create machine user signer-1 { roles = ["roles/signer"] }
create machine user signer-2 { roles = ["roles/signer"] }

# create default invite credentials
create invite credential for connector-1 { public_key = invite-public(hex("connector")) }
create invite credential for connector-1 { public_key = invite-public(hex("oracle")) }
create invite credential for signer-1 { public_key = invite-public(hex("signer-1")) }
create invite credential for signer-2 { public_key = invite-public(hex("signer-2")) }

Additional peers

This blueprint is to setup two peers/nodes. To setup more nodes, you need to add more signer user accounts + invite credentials so they can self-enroll.

For example, adding signer-3 and signer-4.

create machine user signer-3 { roles = ["roles/signer"] }
create machine user signer-4 { roles = ["roles/signer"] }
create invite credential for signer-3 { public_key = invite-public(hex("signer-3")) }
create invite credential for signer-4 { public_key = invite-public(hex("signer-4")) }

Remove root user

This blueprint uses a root user and root access rule that comes out of the box of a Treasury install.

It must be deleted after you are satisfied with your configuration.

treasury features update delete_root true --sign-with root-key