Configuring permissions for application access control
Set up a permission system on your SecureAuth tenant to control access to resources and applications. A permission system holds a schema of object types, relations, and permissions. Your application stores relationships against the schema and calls a check API to decide whether a subject can act on a resource.
Create a permission system
-
Select Permission Systems on the left navigation panel.
Click the Settings button and select Permission Systems in the drop-down, if you're within a workspace.
-
Click + CREATE SYSTEM in the Permission Systems section.
-
Set the permission system name, description, and prefix. Click Create.
PrefixBy default, the prefix combines your tenant name and the name of your permission system. You can modify the prefix at the permission system creation step. Once the permission system is all set, use the prefix value exactly as you see it under the Configuration tab.
-
Click your newly created permission system tile. Proceed with the steps specified under the Quickstart tab.
Create a token
-
Go to the Tokens tab. Click + ADD TOKEN.
-
Set the token name and description. Click Create.
Save your token API key
The API key value is displayed only once, at the token creation step.
An API key is automatically generated for your new token. The API key is required for further work with your permission system. Copy the API key. Make sure it's stored securely.
At any time, you can generate a new token along with the matching API key. Any subsequent token usage requires switching the zed context. Read Further Steps for details.
Apply a schema
-
Copy the
schemavalue. -
Go to the Schema tab. Paste the schema copied to the code block.
-
Save your changes.
The template given below illustrates a basic schema to be created from scratch. It includes a subject type = user, a resource type = post, the relations, and permissions. Based on the schema, you'll add and handle actual subjects and resources to the permission system data table.
You can modify the schema according to your requirements, replacing the $-variables with the actual values.
Use the schema language reference for advanced guidance.
Schema Template
definition ${PREFIX}user {}
definition ${PREFIX}post {
relation reader: ${PREFIX}user
relation writer: ${PREFIX}user
permission read = reader + writer
permission write = writer
}
Store relationships
Now you can record the actual values to your permission system data table.
Call the endpoint provided in the Store relationships block. SecureAuth SecureAuth generates the request_url value for your tenant with the $PERMISSION_SYSTEM_ID retrieved.
The resource and subject IDs are your target resources (for example, post, organization, or whatever else) and actual users or applications to whom you grant permissions.
The WriteRelationsResponse response includes the revision value. Save this value for the Check Permissions step and for further operations with your permission system.
Store Relationships CURL Template
curl -X POST "https://$TENANT_ID.$REGION_ID.connect.secureauth.com/api/permissions/default/system/systems/$PERMISSION_SYSTEM_ID/relationships" \
-H "X-Api-Key: $API_KEY" \
-d '{ "updates": [{
"operation": "upsert",
"relation": "writer",
"resource_id": "$RESOURCE_ID",
"resource_type": "${PREFIX}post",
"subject_id": "$SUBJECT_ID",
"subject_type": "${PREFIX}user"
}] }'
Check permissions
Once the schema is applied and relationships stored, you can check permissions. For this, make a test call with the cURL provided in the Check permissions Quickstart block.
Or use the template below, replacing the $-variables with your custom values, if any, and calling your response_url.
Check Permissions CURL Template
curl -X POST "https://$TENANT_ID.$REGION_ID.connect.secureauth.com/api/permissions/default/system/systems/$PERMISSION_SYSTEM_ID/check" \
-H "X-Api-Key: $API_KEY" \
-d '{
"revision": "$REVISION_VALUE",
"permission": "read",
"resource_id": "$RESOURCE_ID",
"resource_type": "${PREFIX}post",
"subject_id": "$SUBJECT_ID",
"subject_type": "${PREFIX}user"
}'
A successful call answers with the verdict alone:
{"has_permission":true}
Get started with gRPC
Everything you can do over REST is also available over gRPC. SecureAuth exposes the SpiceDB
authzed.api.v1 API, so the official zed command-line tool and
every SpiceDB SDK work
against it unchanged.
Endpoint and authentication
| Address | grpc.$REGION_ID.connect.secureauth.com:443 |
| Transport | TLS, with a publicly trusted certificate. Never use a plaintext or insecure flag. |
| Credentials | Your API key, sent as a bearer token. |
The API key identifies both the tenant and the permission system, so neither appears in the call. This is the main difference from REST, where both sit in the request path.
Install zed
brew install authzed/tap/zed
Other installation options are listed in the zed
repository. On macOS, note that the
Zed editor installs a command of the same name. If zed version prints an
editor version, the permission system commands below will not work until you resolve the conflict.
Run your first check
Pass the endpoint and the token as flags:
zed permission check ${PREFIX}post:$RESOURCE_ID read ${PREFIX}user:$SUBJECT_ID \
--endpoint grpc.$REGION_ID.connect.secureauth.com:443 --token $API_KEY \
--skip-version-check
true means the subject has the permission. Add --json for a machine-readable response that also
carries the current revision as a checkedAt token.
--skip-version-check is needed because SecureAuth does not expose the SpiceDB version service.
To avoid repeating the flags, store them as a context instead:
zed context set secureauth grpc.$REGION_ID.connect.secureauth.com:443 $API_KEY
zed permission check ${PREFIX}post:$RESOURCE_ID read ${PREFIX}user:$SUBJECT_ID --skip-version-check
Creating a new token under the Tokens tab means switching the context to the new API key.
Other operations
zed schema read
zed relationship create ${PREFIX}post:$RESOURCE_ID writer ${PREFIX}user:$SUBJECT_ID
zed relationship read ${PREFIX}post:$RESOURCE_ID
zed permission lookup-resources ${PREFIX}post read ${PREFIX}user:$SUBJECT_ID
zed permission lookup-subjects ${PREFIX}post:$RESOURCE_ID read ${PREFIX}user
Consistency
By default a check is answered from whichever revision the database finds fastest, which can be older than a relationship you have just written. To read your own writes, pass the revision from the write response:
zed permission check ${PREFIX}post:$RESOURCE_ID read ${PREFIX}user:$SUBJECT_ID \
--consistency-at-least $REVISION_VALUE --skip-version-check
Use an SDK
The same endpoint and token work from any SpiceDB client library. In Go:
client, err := authzed.NewClient(
"grpc.$REGION_ID.connect.secureauth.com:443",
grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})),
grpc.WithPerRPCCredentials(oauth.TokenSource{TokenSource: oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: os.Getenv("API_KEY"), TokenType: "Bearer"},
)}),
)
if err != nil {
log.Fatal(err)
}
resp, err := client.CheckPermission(ctx, &pb.CheckPermissionRequest{
Resource: &pb.ObjectReference{ObjectType: "${PREFIX}post", ObjectId: "1"},
Permission: "read",
Subject: &pb.SubjectReference{Object: &pb.ObjectReference{ObjectType: "${PREFIX}user", ObjectId: "emilia"}},
})
resp.Permissionship is PERMISSIONSHIP_HAS_PERMISSION when the subject has the permission.
Object types always carry your permission system prefix. A call that references an unprefixed type, or a type from another permission system, is rejected.
Variable reference
-
$TENANT_IDand$REGION_ID: The first two labels of your admin console address. Forhttps://acme.us.connect.secureauth.com, the tenant isacmeand the region isus. The tenant segment in the request path is separate: it'sdefaulton SecureAuth-hosted deployments, and your tenant identifier on a self-hosted installation. -
$API_KEY: The API key generated for the token you've created at the first step. Store it for any further calls. -
$PREFIX: Your permission system prefix set at the permission system creation step, exactly as shown under the Configuration tab. It already ends with a slash, so it's concatenated with the object type rather than joined by one. It correlates the schema objects with the permission system. -
$PERMISSION_SYSTEM_ID: Your permission system identifier. You can find it in the response URL parameter generated for your permission system within the Quickstart blocks or in the address bar when you're on the permission system page. -
$RESOURCE_ID: The resource identifier. It defines what is to be accessed by the subject. -
$SUBJECT_ID: The identifier of the subject. It defines who or what has permissions relating to the target resource. -
$REVISION_VALUE: The revision value you've obtained with theWriteRelationsResponseparameter upon the Store Relationships step.
Further steps
Once your permission system is all set, it's available for further management. With SecureAuth permission system APIs cover the full range of operations to handle permissions from creation through checks to removal, including:
-
Lookup resources to get the list of resources that have any subject assigned.
-
Lookup subjects to get the list of subjects with access to resources.
-
Handle token, including its update when the existing token isn't available.
You can also generate a new token with the matching API key under the Tokens tab in your permission system settings.
SecureAuth Permission System uses SpiceDB as authorization data storage, so the SpiceDB command-line tool and SDKs work against it directly. See Get started with gRPC.
The Check it out blog post explains how permission systems work in detail.