Dynamic Policies
The SSIKit allows for specifying custom policies written in one of the supported policy engine lingos.
A dynamic policy can be executed on the fly, if all required parameters are given, or saved with a name, by which it can be referenced in the verify command or REST API lateron.
In this example I'm going to use a very simple policy written in the Rego language, for the Open Policy Agent engine.
The dynamic policy requires an argument of the DynamicPolicyArg type, which is defined like follows:
data class DynamicPolicyArg (
val name: String = "DynamicPolicy",
val description: String? = null,
val input: Map<String, Any?>,
val policy: String,
val dataPath: String = "\$",
val policyQuery: String = "data.system.main",
val policyEngine: PolicyEngineType = PolicyEngineType.OPA,
val applyToVC: Boolean = true,
val applyToVP: Boolean = false
)
Properties:
name
: policy name, defaults to "DynamicPolicy"description
: Optional description of the policyinput
: A generic map (JSON object), holding the input data required by the policy (or an empty map if no input is required)policy
: the policy definition (e.g. rego file), which can be a file path, URL, JSON Path (if policy is defined in a credential property) or the code/script directly.dataPath
: The path to the credential data, which should be verified, by default it's the whole credential object$
. To use e.g. only the credential subject as verification data, specify the JSON path like this:$.credentialSubject
.policyQuery
: The query string in the policy engine lingo, defaults to "data.system.main"policyEngine
: The engine to use for execution of the policy. By defaultOPA
(Open Policy Agent) is used.applyToVC
: Apply this policy to verifiable credentials (Default: true)applyToVP
: Apply this policy to verifiable presentations (Default: false)
The policy is executed by the specified policy engine. Currently the only supported engine is Open Policy Agent.
The Open Policy Agent receives an input object that contains the input parameter of the dynamic policy and the credential data, as configured in the policy argument.
The input object for the policy engine looks like this:
data class PolicyEngineInput(
val credentialData: Map<String, Any?>,
val parameter: Map<String, Any?>?
)
This means, in the definition of the REGO policy, one can access the input parameter and the credential data selected for evaluation, by these input properties:
input.parameter
: The input object as defined in the input
property of the Dynamic Policy Argumentinput.credentialData
: The credential data selected by the JSON path given in the dataPath
property of the Dynamic Policy ArgumentSee the next section for a simple example.
This simple rego policy takes a credential subject as input and verifies the subject DID against a given parameter.
package system
default main = false
main {
input.parameter.user == input.credentialData.credentialSubject.id
}
This policy file is located in the SSIKit test resources:
src/test/resources/rego/subject-policy.rego
To execute the sample policy on the fly, without saving it as custom policy, simply run this command:
ssikit vc verify -p DynamicPolicy='{ "policy": "src/test/resources/rego/subject-policy.rego", "input": { "user": "did:key:z6MkgERd8hghGSBndxduiXtUdbYmtbcX9TeNdAL2BAhvXoAp" } }' src/test/resources/rego/VerifiableId.json
This command uses the DynamicPolicy to execute the rego policy specified in the policy property, with the input specified in the input property.
To save the policy by name, so that it can be used more easily lateron, use the command
ssikit vc policies create
Let's save the above sample policy as
SubjectPolicy
, like so:ssikit vc policies create -n "SubjectPolicy" -D "Verifies credential subject" -p src/test/resources/rego/subject-policy.rego
Now we can simplify the above verify command like this:
ssikit vc verify -p SubjectPolicy='{ "user": "did:key:z6MkgERd8hghGSBndxduiXtUdbYmtbcX9TeNdAL2BAhvXoAp" }' src/test/resources/rego/VerifiableId.json
This policy requires the user did as input.
It's possible to include the policy input argument in the saved policy, to pre-define the input or use it as a default, which can be overridden on execution.
Let's create a saved policy named
ItsMePolicy
, which checks all credentials against my predefined subject DID:ssikit vc policies create -n "ItsMePolicy" -D "Verifies credential subject against my DID" -p src/test/resources/rego/subject-policy.rego -i '{ "user": "did:key:z6MkgERd8hghGSBndxduiXtUdbYmtbcX9TeNdAL2BAhvXoAp" }'
Now we can further simplify the above verify command like this:
ssikit vc verify -p ItsMePolicy src/test/resources/rego/VerifiableId.json
Note, that we can still override the predefined input data like shown here:
ssikit vc verify -p ItsMePolicy='{ "user": "did:key:xxxxxxxxx" }' src/test/resources/rego/VerifiableId.json
To update an existing policy use the
--force
flag of the create command like so:ssikit vc policies create -n "ItsMePolicy" -D "Verifies credential subject against my DID" -p src/test/resources/rego/subject-policy.rego -i '{ "user": "did:key:z6MkgERd8hghGSBndxduiXtUdbYmtbcX9TeNdAL2BAhvXoAp" }' --force
To remove a previously created policy, use the remove command:
ssikit vc policies remove -n ItsMePolicy
Note: You can update and remove only dynamic policies that have been manually created. You cannot override existing predefined, static policies.
The list command indicates mutable policies, by a leading
*
, and provides the -m, --mutable
flags to filter by mutable policies only:> ssikit vc policies list -m
[...]
* GaiaXPolicy - no description -, Argument: JsonObject
* SubjectPolicy Verifies credential subject, Argument: JsonObject
(*) ... mutable dynamic policy
Last modified 5h ago