convex.core.trust.cvx Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of convex-core Show documentation
Show all versions of convex-core Show documentation
Convex core libraries and common utilities
The newest version!
'convex.trust
(call *registry*
(register {:description ["Based on the reference monitor security model."
"See comments about trusted monitors in `trusted?`."
"Provides for creation of upgradable actors."]
:name "Trust monitor library"}))
;;
;; See: https://en.wikipedia.org/wiki/Reference_monitor
;;
;;;;;;;;;; Private
(def -self
^{:private? true}
*address*)
;;;;;;;;;; Checking trust
(defn trust-monitor?
^{:doc {:description "Does `x` look like a trust monitor?"
:examples [{:code "(trust-monitor? #42)"}]
:signature [{:params [x]}]}}
[x]
(callable? x 'check-trusted?))
(defn trusted?
^{:doc {:description ["Returns true if `subject` is trusted by `trust-monitor`, false otherwise."
"A trust monitor is an (optionally scoped) address, pointing to either:"
"- A user account (that can only trust itself)"
"- An actor implementing `(check-trusted? subject action object)` which returns true or false."
"`action` and `object` are arbitrary values specific to the trust monitor."
"`subject` should usually be an address, although this is specific to the trust monitor as well."]
:examples [{:code "(trusted? my-blacklist *caller*)"}]
:signature [{:params [trust-monitor subject]}
{:params [trust-monitor subject action]}
{:params [trust-monitor subject action object]}]}}
([monitor subject]
(recur monitor
subject
nil
nil))
([monitor subject action]
(recur monitor
subject
action
nil))
([monitor subject action object]
(cond
;; General case: call into check-trusted? function if it exists
(callable? monitor 'check-trusted? )
;; SECURITY note: query here is protection against potential re-entrancy attacks.
(query (call monitor
(check-trusted? subject
action
object)))
;; Basic case: check for callable equality
(address? monitor)
(= monitor subject)
false)))
;;;;;;;;;; Control of Actor / scope
(defn change-control
^{:doc {:description ["Sets a controller for an entity (possibly scoped). Controller may be any trust monitor. Typically requires trust from the existing controller, for an action of :control."]
:examples [{:code "(set-control my-asset *address*)"}]
:signature [{:params [path controller]}]}}
[path controller]
(call path (change-control controller))
:OK)
;;;;;;;;;; Upgradable actors
(defn add-trusted-upgrade
^{:doc {:description ["Creates deployable code for an upgradable actor where any arbitrary code can be executed."
"An optional configuration map may be provided:"
"- `:root`, address that can execute arbitrary code in the actor (defaults to `*address*`)"
"Meant to be used wisely."]
:examples [{:code "(deploy (add-trusted-upgrade {:root *address*}))"}]
:signature [{:params [config]}]}}
[config]
(let [root (or (:root config)
*address*)]
`(do
(def trust
~-self)
(def upgradable-root
~root)
(defn change-control
^{:callable true}
[controller]
(or
(trust/trusted? upgradable-root *caller* :control *address*)
(fail :TRUST "Not allowed to update controller"))
(cond
(nil? *scope*) (def upgradable-root controller)
(fail :ARGUMENT "Unexpected non-nil scope")))
(defn upgrade
^{:callable true}
[code]
(if (trust/trusted? upgradable-root *caller* :upgrade *address*)
(eval code)
(fail :TRUST "No access to upgrade capability!"))))))
(defn add-controller
^{:doc {:description ["Creates deployable code to add a controller to an actor."
]
:examples [{:code "(deploy (add-trusted-upgrade {:root *address*}))"}]
:signature [{:params []}
{:params [controller]}]}}
([] (recur *address*))
([cont]
`(set-controller ~cont)))
(defn remove-upgradability!
^{:doc {:description ["Removes upgradability from an actor, previously added using `add-trusted-upgrade`."
"Cannot be undone, meant to be used wisely after considering all implications."]
:examples [{:code "(remove-upgradability! upgradable-actor)"}]
:signature [{:params [config]}]}}
[actor]
(call actor
(upgrade
'(do
;; Undefine things used for upgradability
(undef upgrade)
(undef upgradable-root))))
nil)