Access rules
Access rules are needed in order for any kind of request to Treasury to succeed. Without them, requests will be denied by default.
Setup
For the examples, we will assume a fresh treasury instance or demo, which you can start to follow along.
treasury demo start --port 8777 --pull
While you can create rules & resources using the treasury
CLI,
using the CSL interpreter is often easier & more consistent.
Open the CSL interpreter by running:
treasury script --sign-with root-key
Note that the demo comes configured with a few rules built-in, including this rule which permits the "root" user to do anything.
allow access-rule root { action = "any/action", resource = "any/resource", initiate = "users/root" }
For the examples, we'll create an alice
& bob
users that doesn't yet have permission to do anything.
# create a fresh role called "demo"
treasury roles create demo
# create users alice & bob
treasury users create machine alice --role demo
treasury users create machine bob --role demo
# create invite codes
treasury credentials create-invite alice "alices_invite_code"
treasury credentials create-invite bob "bobs_invite_code"
# create + enroll new local client credentials that alice & bob can sign with.
treasury credentials register alice-key --invite "alices_invite_code" --create-new
treasury credentials register bob-key --invite "bobs_invite_code" --create-new
# test sending requests as both alice + bob
treasury users heartbeat --sign-with alice-key
treasury users heartbeat --sign-with bob-key
Dry-running
Note that at any point you can dry-run various requests without having to sign any request. Such dry-runs do not actually cause any state change, but can be helpful for testing or debugging policies.
Dry-runs will return helpful traces on rules that matched the request. You'll be able to see how each rule evaluated.
Using curl:
curl -H 'dry-run: user=root' -X POST -d '{"from":"chains/SOL/addresses/<from>", "to":"chains/SOL/addresses/<to>", "amount":"100", "asset":"chains/SOL/assets/SOL"}' localhost:8777/v1/transfers
Using CLI:
treasury transfers create --from "<from>" --to "<to>" --chain SOL 100 --dry-run 'user=root'
Examples
Default deny
By default, users cannot do anything unless they are included in a matching rule, whether by their username or by their role (or wildcard).
- CSL
- CSL
# Doesn't work
set sign.with = alice-key
create machine user carol
# Doesn't work
treasury users create machine carol --sign-with alice-key
Allow rule
We could permit alice or bob to create addresses, either by their specific user name(s), or by their role ("roles/demo").
- CSL
- CSL
# allow alice
create allow access-rule ALLOW_ADDRESSES { resource = "Address", initiate = "users/alice", action = ["create", "update", "delete"] }
# alice creates an address
set sign.with = alice-key
create internal address for SOL
# allow alice
treasury access-rules create allow ALLOW_ADDRESSES --resource addresses --initiate users/alice --action create,update,delete
# alice creates an address
treasury addresses create SOL --sign-with alice-key
Deny rule
Let's permit any with "demo" role to create addresses, but we deny alice
from doing so.
- CSL
- CSL
create allow access-rule ALLOW_ADDRESSES { resource = "Address", initiate = "roles/demo", action = ["create", "update", "delete"] }
create deny access-rule DENY_ADDRESSES { resource = "Address", initiate = "users/alice", action = ["create", "update", "delete"] }
# bob is allowed
set sign.with = bob-key
treasury addresses create SOL --sign-with alice-key
# but not alice
set sign.with = alice-key
treasury addresses create SOL --sign-with alice-key
# allow
treasury access-rules create allow ALLOW_ADDRESSES --resource addresses --initiate roles/demo --action create,update,delete
treasury access-rules create deny DENY_ADDRESSES --resource addresses --initiate users/alice --action create,update,delete
# bob is allowed
treasury addresses create SOL --sign-with bob-key
# but not alice
treasury addresses create SOL --sign-with alice-key
Require rule
Let's require that creating addresses needs an approval.
Approval conditions can also be used with allow
rules, but those would only apply to the specific rule.
The require
variant on the other hand, must always be satisfied if it matches a request. Note that you always need to have a matching allow rule for a request to pass; a require rule by itself is not sufficient.
create allow access-rule ALLOW_ADDRESSES { resource = "Address", initiate = "roles/demo", action = ["create", "update", "delete"] }
create require access-rule REQUIRE_ADDRESSES { resource = "Address", initiate = "roles/demo", approve="roles/demo", approvals=1, action = ["create", "update", "delete"] }
# delete any deny rules you may have made
_, _ = delete access-rule DENY_ADDRESSES
To test this out:
# note this returns an operation in `authorizing` state.
treasury addresses create SOL --sign-with alice-key
# another roles/demo user will need to approve to complete:
treasury operations approve "<operation-id>" --sign-with bob-key
Data filters
We can match rules based on any filter in the data of the target resource.
Let's suppose we have a special key and we want to require approvals for who can sign with it.
# create a key called "COLD_KEY"
treasury keys create --algorithm ed255 COLD_KEY
# create a key called "HOT_KEY"
treasury keys create --algorithm ed255 HOT_KEY
Now we can require that any signature request needs an approval from a "roles/demo" user.
# permit people to create signatures
create allow access-rule ALLOW_SIGNATURES { resource = "Signature", initiate = "roles/demo", action = "create" }
# require approval for using the COLD_KEY
create require access-rule REQUIRE_SIGNATURES { resource = "Signature", data = {key = "keys/COLD_KEY"}, initiate = "any/user", approve="roles/demo", approvals=1, action = "create" }
To try this out, we can see that we can payloads using the "HOT_KEY" without approval.
treasury signatures create --key HOT_KEY --message 1234 --sign-with alice-key
Using "COLD_KEY" will require approval.
treasury signatures create --key COLD_KEY --message 1234 --sign-with alice-key
# approve
treasury operations approve "<operation-id>" --sign-with bob-key
Approve only
To permit someone only to approve, you need only omit the initiate
and pass only the approve
& approvals
conditions.
Wildcards are specified explicity with either any/action
, any/resource
, or any/user
.
allow access-rule APPROVE_ONLY { creator = "users/root", version = 1, action = "any/action", resource = "any/resource", approve = "users/root", approvals = 1 }