Minka Ledger Docs
Explanations

About Security Policies

DateResponsibleChanges
June 14, 2023@Luis FidelisInitial version
July 19, 2023@Luis FidelisAdd properties invoke and filter of policy values
July 15, 2024@Luis Fidelis• Moved About Policies to About Security Policies.
• Add schema: access to security policies.
October 23, 2024@Tomislav BradaricUpdated security policies built-in functions table to note that debit acts like forward when it comes to access rights during creation (has to have access to spend from the route target)

What is a security policy?

A security policy is a ledger record that represents a set of access rules that can be attached to records.

{
    "data": {
        "handle": "bank",
        "record": "wallet",
        "schema": "access",
        "values": [{
            "action": "update",
            "signer": {
                "$circle": "bank-circle"
            }
        }, {
            "action": "read",
            "bearer": {
                "$signer": {
                    "$circle": "bank-circle"
                }
            }
        }],
        "custom": {
        ...
        },
        "access": [...],
    },   
    "hash": "...",
    "meta": {...}
}

Targeting records - record

To create a policy it is necessary to define the target class of record which can reuse it and it's done with record and filter properties.

Below, there are some examples of policies that defines security rules to be used by ledger records.

{
    "data": {
        "handle": "signer-management",
        "record": "signer",
        "schema": "access",
        "values": [{
            "action": "update",
            "signer": {
                "$circle": "owner"
            }
        }, {
            "action": "read",
            "bearer": {
                "$signer": {
                    "$circle": "owner"
                }
            }
        }],
        "custom": {
        ...
        },
        "access": [...],
    },   
    "hash": "...",
    "meta": {...}
}
{
    "data": {
        "handle": "record-factory",
        "record": "any",
        "schema": "access",
        "values": [{
            "action": "create",
            "signer": {
                "$circle": "owner"
            }
        }],
        "custom": {
        ...
        },
        "access": [...],
    },   
    "hash": "...",
    "meta": {...}
}
{
    "data": {
        "handle": "wallet-reader",
        "record": "wallet",
        "schema": "access",
        "filter": {
            "schema": "bank-wallet" 
        },
        "values": [{
            "action": "read",
            "signer": {
                "$circle": "bank"
            }
        }],
        "custom": {
        ...
        },
        "access": [...],
    },   
    "hash": "...",
    "meta": {...}
}

Extending policies - extend

Policies can be extended, which means that one policy can reuse values of an existing policy by using the property extend

// Policy "reader"
{
    "data": {
        "handle": "reader",
        "record": "any",
        "schema": "access",
        "values": [{
            "action": "read",
            "signer": {
                "$circle": "admin"
            }
        }],
        "custom": {
        ...
        },
        "access": [...],
    },   
    "hash": "...",
    "meta": {...}
}
 
// Policy "wallet-reader"
{
    "data": {
        "handle": "wallet-reader", 
        "extend": "reader",
        "record": "wallet",
        "values": [{
            "action": "read",
            "signer": {
                "$circle": "bank"
            }
        }],
        "custom": {
        ...
        },
        "access": [...],
    },   
    "hash": "...",
    "meta": {...}
}

Adding filter to policy values - filter

Policy values accepts filter, which is used to filter to which records the value applies. Filter can be defined with any content, and its value is used to match properties of a record data.

// Symbol "usd"
{
    "data": {
        "handle": "usd",
        "factor": 100,
        "schema": "fiat",
        ...
    },   
    "hash": "...",
    "meta": {...}
}
 
// Symbol "bitcoin"
{
    "data": {
        "handle": "bitcoin",
        "factor": 100000000,
        "schema": "crypto",
        ...
    },   
    "hash": "...",
    "meta": {...}
}
 
// Policy "symbol-reader"
{
    "data": {
        "handle": "symbol-reader", 
        "record": "symbol",
        "schema": "access",
        "values": [{
            "action": "read",
            "signer": {
                "$circle": "bank"
            },
            "filter": {
                "schema": "fiat"
            },
        }, {
            "action": "read",
            "signer": {
                "$circle": "exchange"
            },
            "filter": {
                "schema": "crypto"
            }
        }],
        "custom": {
        ...
        },
        "access": [...],
    },   
    "hash": "...",
    "meta": {...}
}

Attaching built-in functions to policy values - invoke

Policy values accepts invoke, which can be used to attach built-in functions to policies.

Follow the functions implemented and their respective records.

RECORDFUNCTION NAMEDescription
walletwallet.canSpendAllChangedRouteTargetsA route of action forward or debit can be added to a wallet only if the signer has access to spend the target wallet of the route.
intentintent.canReadAnyClaimWalletAn intent can be read only if the user is allowed to read any of the wallets involved in any claim of this intent as source or target.
intentintent.canReadAnyClaimWalletInThreadAn intent can be read only if the user is allowed to read any of the wallets involved in any claim of the thread that this intent is part of - as source or target. For intent threads with a single intent, this function has the same effect of intent.canReadAnyClaimWallet
intentintent.canSpendEveryClaimWalletIntents can be created only if the signer has access to spend all the participant wallets of this intent - as source and target .
// Policy "wallet-mutation"
{
    "data": {
        "handle": "wallet-mutation", 
        "record": "wallet",
        "schema": "access",
        "values": [{
            "action": "create",
            "invoke": "wallet.canSpendAllChangedRouteTargets"
        }, {
            "action": "update",
            "invoke": "wallet.canSpendAllChangedRouteTargets"
        }],
        "custom": {
        ...
        },
        "access": [...],
    },   
    "hash": "...",
    "meta": {...}
}

Policy usage

A policy can be attached to access rules of ledger records by referencing its handle

{
    "data": {
        "handle": "bank-wallet",
        "custom": {
        ...
        },
        "access": [{
            "policy": "bank"
        }],
    },   
    "hash": "...",
    "meta": {...}
}

Policies can be also reused alongside regular access rules.

{
    "data": {
        "handle": "bank-wallet",
        "custom": {
        ...
        },
        "access": [{
            "policy": "bank"
        }, {
            "action": "spend",
            "signer": {
                "handle": "treasury"
            }
        }],
    },   
    "hash": "...",
    "meta": {...}
}

Security policies are powerful since they centralize security rules and ease their management. See About Authorization for more details.

On this page