Skip to main content

Tests

Topaz makes it easy to define and run a set of test cases known as assertions, to help test the model and prove that it authorizes correctly.

Defining assertions

Assertions are managed in a JSON file, by default named assertions.json.

There are two types of assertions:

  • Directory assertions, or check: define a test case that checks whether a relation (or permission) exists between an object (identified by object_type and object_id) and a subject (identified by subject_type, subject_id, and optionally subject_relation).
  • Authorizer assertions, or check_decision: define a test case that executes the authorizer is API over the given identity_context, resource_context, and policy_context

Both types of assertions also include an expected key, which can be either true or false depending on whether the assertion is supposed to succeed or fail.

note

The check_relation and check_permission are shown for backward-compatibility but are no longer used.

Directory assertions

topaz directory test template emits a skeleton assertions file to stdout.

Example:

topaz directory test template
{
"assertions": [
{"check": {"object_type": "", "object_id": "", "relation": "", "subject_type": "", "subject_id": ""}, "expected": true},
{"check_relation": {"object_type": "", "object_id": "", "relation": "", "subject_type": "", "subject_id": ""}, "expected": true},
{"check_permission": {"object_type": "", "object_id": "", "permission": "", "subject_type": "", "subject_id": ""}, "expected": true},
]
}
note

You should only use the check assertions. The check_relation and check_permission assertinos will be removed in a future release.

Authorizer assertions

topaz authorizer test template emits a skeleton authorizer assertions file to stdout.

Example:

topaz authorizer test template
{
"assertions": [
{"check_decision": {"identity_context": {"identity": "", "type": ""}, "resource_context": {}, "policy_context": {"path": "", "decisions": [""]}}, "expected":true},
]
}

Running assertions

Directory assertions

topaz directory test exec executes the assertions in a JSON file of the proper format, defaulting to ./assertions.json. To specify a different file name, use the filename argument.

Example:

  1. Create the following assertions.json file, which defines a set of test cases for the data in the todo template:
{
"assertions": [
{
"check": {
"subject_type": "user",
"subject_id": "rick@the-citadel.com",
"relation": "member",
"object_type": "group",
"object_id": "admin"
},
"expected": true
},
{
"check": {
"subject_type": "user",
"subject_id": "rick@the-citadel.com",
"relation": "member",
"object_type": "group",
"object_id": "evil_genius"
},
"expected": true
},
{
"check": {
"subject_type": "user",
"subject_id": "rick@the-citadel.com",
"relation": "member",
"object_type": "group",
"object_id": "editor"
},
"expected": false
},
{
"check": {
"subject_type": "user",
"subject_id": "rick@the-citadel.com",
"relation": "member",
"object_type": "group",
"object_id": "viewer"
},
"expected": false
},

{
"check": {
"subject_type": "user",
"subject_id": "morty@the-citadel.com",
"relation": "member",
"object_type": "group",
"object_id": "admin"
},
"expected": false
},
{
"check": {
"subject_type": "user",
"subject_id": "morty@the-citadel.com",
"relation": "member",
"object_type": "group",
"object_id": "evil_genius"
},
"expected": false
},
{
"check": {
"subject_type": "user",
"subject_id": "morty@the-citadel.com",
"relation": "member",
"object_type": "group",
"object_id": "editor"
},
"expected": true
},
{
"check": {
"subject_type": "user",
"subject_id": "morty@the-citadel.com",
"relation": "member",
"object_type": "group",
"object_id": "viewer"
},
"expected": false
},

{
"check": {
"subject_type": "user",
"subject_id": "summer@the-smiths.com",
"relation": "member",
"object_type": "group",
"object_id": "admin"
},
"expected": false
},
{
"check": {
"subject_type": "user",
"subject_id": "summer@the-smiths.com",
"relation": "member",
"object_type": "group",
"object_id": "evil_genius"
},
"expected": false
},
{
"check": {
"subject_type": "user",
"subject_id": "summer@the-smiths.com",
"relation": "member",
"object_type": "group",
"object_id": "editor"
},
"expected": true
},
{
"check": {
"subject_type": "user",
"subject_id": "summer@the-smiths.com",
"relation": "member",
"object_type": "group",
"object_id": "viewer"
},
"expected": false
},

{
"check": {
"subject_type": "user",
"subject_id": "beth@the-smiths.com",
"relation": "member",
"object_type": "group",
"object_id": "admin"
},
"expected": false
},
{
"check": {
"subject_type": "user",
"subject_id": "beth@the-smiths.com",
"relation": "member",
"object_type": "group",
"object_id": "evil_genius"
},
"expected": false
},
{
"check": {
"subject_type": "user",
"subject_id": "beth@the-smiths.com",
"relation": "member",
"object_type": "group",
"object_id": "editor"
},
"expected": false
},
{
"check": {
"subject_type": "user",
"subject_id": "beth@the-smiths.com",
"relation": "member",
"object_type": "group",
"object_id": "viewer"
},
"expected": true
},

{
"check": {
"subject_type": "user",
"subject_id": "jerry@the-smiths.com",
"relation": "member",
"object_type": "group",
"object_id": "admin"
},
"expected": false
},
{
"check": {
"subject_type": "user",
"subject_id": "jerry@the-smiths.com",
"relation": "member",
"object_type": "group",
"object_id": "evil_genius"
},
"expected": false
},
{
"check": {
"subject_type": "user",
"subject_id": "jerry@the-smiths.com",
"relation": "member",
"object_type": "group",
"object_id": "editor"
},
"expected": false
},
{
"check": {
"subject_type": "user",
"subject_id": "jerry@the-smiths.com",
"relation": "member",
"object_type": "group",
"object_id": "viewer"
},
"expected": true
}
]
}
  1. Run the test suite:
topaz directory test exec -i
0001 check PASS group:admin#member@user:rick@the-citadel.com [true] (2.764667ms)
0002 check PASS group:evil_genius#member@user:rick@the-citadel.com [true] (1.545541ms)
0003 check PASS group:editor#member@user:rick@the-citadel.com [false] (1.665166ms)
0004 check PASS group:viewer#member@user:rick@the-citadel.com [false] (1.583125ms)
0005 check PASS group:admin#member@user:morty@the-citadel.com [false] (1.369542ms)
0006 check PASS group:evil_genius#member@user:morty@the-citadel.com [false] (1.399875ms)
0007 check PASS group:editor#member@user:morty@the-citadel.com [true] (1.297292ms)
0008 check PASS group:viewer#member@user:morty@the-citadel.com [false] (1.375917ms)
0009 check PASS group:admin#member@user:summer@the-smiths.com [false] (1.498042ms)
0010 check PASS group:evil_genius#member@user:summer@the-smiths.com [false] (1.34ms)
0011 check PASS group:editor#member@user:summer@the-smiths.com [true] (1.349875ms)
0012 check PASS group:viewer#member@user:summer@the-smiths.com [false] (1.328584ms)
0013 check PASS group:admin#member@user:beth@the-smiths.com [false] (1.364667ms)
0014 check PASS group:evil_genius#member@user:beth@the-smiths.com [false] (1.412834ms)
0015 check PASS group:editor#member@user:beth@the-smiths.com [false] (1.781375ms)
0016 check PASS group:viewer#member@user:beth@the-smiths.com [true] (1.782375ms)
0017 check PASS group:admin#member@user:jerry@the-smiths.com [false] (1.790791ms)
0018 check PASS group:evil_genius#member@user:jerry@the-smiths.com [false] (1.44825ms)
0019 check PASS group:editor#member@user:jerry@the-smiths.com [false] (1.366709ms)
0020 check PASS group:viewer#member@user:jerry@the-smiths.com [true] (1.349167ms)

Authorizer assertions

topaz authorizer test exec executes the assertions in a JSON file of the proper format, defaulting to ./assertions.json. To specify a different file name, use the filename argument.

Example:

  1. Create the following assertions.json file, which defines a set of test cases for the data in the todo template:
{
"assertions": [
{
"check_decision": {
"identity_context": { "identity": "rick@the-citadel.com", "type": "IDENTITY_TYPE_SUB" },
"resource_context": {},
"policy_context": { "path": "todoApp.GET.todos", "decisions": ["allowed"] }
},
"expected": true
},
{
"check_decision": {
"identity_context": { "identity": "morty@the-citadel.com", "type": "IDENTITY_TYPE_SUB" },
"resource_context": { "object_type": "resource-creator", "object_id": "resource-creators", "relation": "member" },
"policy_context": { "path": "todoApp.POST.todos", "decisions": ["allowed"] }
},
"expected": true
},
{
"check_decision": {
"identity_context": { "identity": "jerry@the-smiths.com", "type": "IDENTITY_TYPE_SUB" },
"resource_context": {},
"policy_context": { "path": "todoApp.GET.todos", "decisions": ["allowed"] }
},
"expected": true
},
{
"check_decision": {
"identity_context": { "identity": "jerry@the-smiths.com", "type": "IDENTITY_TYPE_SUB" },
"resource_context": { "object_type": "resource-creator", "object_id": "resource-creators", "relation": "member" },
"policy_context": { "path": "todoApp.POST.todos", "decisions": ["allowed"] }
},
"expected": false
}
]
}
  1. Run the test suite:
topaz authorizer test exec -i
0001 check_decision PASS todoApp.GET.todos/allowed:rick@the-citadel.com [true] (65.22175ms)
0002 check_decision PASS todoApp.POST.todos/allowed:morty@the-citadel.com [true] (3.702959ms)
0003 check_decision PASS todoApp.GET.todos/allowed:jerry@the-smiths.com [true] (2.012125ms)
0004 check_decision PASS todoApp.POST.todos/allowed:jerry@the-smiths.com [false] (2.7505ms)