About Status Policies
Date | Responsible | Changes |
---|---|---|
July 15, 2024 | @Luis Fidelis | Initial version |
What is a status policy?
Status policies are used to define which custom statuses a record can have as well as the required quorum to change to these statuses. They have schema status
which defines a specific structure of policy rules contained in values
of the policy.
At root level, the status policy can have fields which limit the policy to specific records:
record
- defines that policy is only for specific record type, optional, if not defined policy applies to all record typesfilter
- record must match the filter in order for policy to be applied to it, optional, if not defined policy applies to all records
The principle open unless whitelisted
which we follow in all kinds of ledger rules is valid here also. So if for a record whose status is to be changed there is not any matching status policy (by record and filter) then the operation will be accepted. Otherwise the operation needs to be explicitly granted by one of applicable policy rules.
Property filter
represents standard ledger filtering concept where language used in filter expression is mongo-compatible. This concept is already used in: access rules and effects.
Statuses policies are exposed on the same endpoint as access policies with distinction that the schema property is equal to status
while for access policies schema is access
. Schema of the policy record defines the structure of values
array in policy.
Constraining quorum for statuses
In the above case, in order for status to be changed there must be a proof with custom.status
made by a signer with public key WAweF9PHlboQoW0z8NqhZXFmzUTaV74NRFAd/aILprE=
as specified in the quorum
field of a policy. Quorum is array of signer references which follows the same structure as the signer references in access rules and policies. For example record owner can also be referenced in policy by using "quorum": [{ "$record": "owner" }]
.
If based on policies, the signer is not in quorum required to set a status, or if additional proofs are required by quorum list, there will be no error. Only side effect will be that proof with status will be stored in record proofs but record status will not be changed.
Except quorum
, the rule in status policy has optional field status
which makes a rule applicable only to specific status. The policy below will requires a proof from signer(public) AweF9PHlboQoW0z8NqhZXFmzUTaV74NRFAd/aILprE=
to change wallet
status to "active"
. Setting other statuses to wallet will not be allowed unless there is another policy/rule which grants that explicitly.
By default the status
in policy rule is string and in this form it represents equality. It can also be a valid mongo compatible sub-expression for matching single object field as shown below by using $in
.
To define a quorum for removing a label from a record, there is special value null
. The same value is used in proofs for requesting the status removal.
A rule can also allow combination of removing and setting specific statuses, for example: "status": { $in: ["active", "inactive", null] }
Status policies evaluation
When evaluating status policies for setting a status to record there can be multiple matching policies with multiple values and multiple signers in quorum. To easier understand how they are combined the following rules are applied top-down:
-
If there is at least one status policy which matches the record by
record
andfilter
then, in order to allow setting the status of record, at least one policy must be found which allows setting this specific status based on policy rules. If there are no matching policies, then setting of status is allowed to anyone. -
Policy can have multiple rules in
values
field and it is considered that the policy grants setting status to record if at least one rule is found which grants this for this specific status. Emptyvalues
array grants nothing. -
Single rule can have
status
field which when exists will make rule applicable only if the desired status matches. Ifstatus
field is omitted then the rule allows all statuses - according to quorum.If there is any policy which matches
record/filter
for a record but none of them explicitly allows setting specific status then the proof which is to be added is not valid and will be rejected. Proof will not be stored and error response will be returned to caller. Restrictive nature of fieldstatus
in policy rule is opposite than fieldswallet, filter
in policy. While setting specificwallet
and/orfilter
in the policy will narrow status restrictions only to records which matches them, setting the specificstatus
in policy rule will narrow the set of acceptable statuses this rule can apply to. So interpretation that rule withstatus: 'active'
implies thatquorum
is required only for statusactive
is wrong. Correct interpretation is that this rule with itsquorum
can be used only to grant setting statusactive
. -
Rule also has
quorum
array of signer references and it is used to determine when the status from the proof can be persisted to a record. Quorum step will be evaluated only after all previous steps are executed successfully and the specific status from proof is allowed. Status will be persisted to a record only when all signers referenced in quorum had signed the record with a proof which has the desired status incustom.status
. Emptyquorum
array means that quorum is not required and will cause that status is persisted to record immediately.If a proof with
status
passes steps 1.-4. but the key used in this proof is not in the quorum or if another key is required to fulfill the quorum then the proof will be stored successfully, error will not be returned to caller, but status will not be persisted to record until the quorum of the rule which allows this status is achieved. -
When taking existing proofs from a record to evaluate
quorum
there is special constraint that only last N signatures with same status are taken into consideration. This is required so that proofs used in past to set some status cannot be reused to set this status again in future. This rule is easy to demonstrate and remember with this example:~~activated activated deactivated deactivated~~ activated
When a record is modified, it may fall under a policy that it does not satisfy. For example, there could be a wallet status policy that requires a signature from a specific key, but only if the wallet record has a schema like fintech
. In this scenario, someone could first create a wallet without a schema or with a schema such as bank
, then set the status to active
and afterward change the schema to fintech
. As a result, the wallet status is now subject to the policy, but the status was set without enforcing this policy.