Skip to content

Copy-Paste Integration Path

The following path creates a minimal invoice.approve authorization setup. It assumes:

Terminal window
export PLYSTRA_URL=http://localhost:8080
export PLYSTRA_TOKEN=<alice-or-super-admin-access-token>
Terminal window
curl -s -X POST "$PLYSTRA_URL/api/v1/auth/login" \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]","password":"plystra-demo"}'

Store the returned data.access_token in PLYSTRA_TOKEN.

Terminal window
curl -s -X POST "$PLYSTRA_URL/api/v1/resource-types" \
-H "Authorization: Bearer $PLYSTRA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "rt_invoice",
"key": "invoice",
"display_name": "Invoice",
"description": "Invoices mirrored from the billing system",
"source": "core"
}'
Terminal window
curl -s -X POST "$PLYSTRA_URL/api/v1/resource-types/invoice/actions" \
-H "Authorization: Bearer $PLYSTRA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "ra_invoice_approve",
"key": "approve",
"display_name": "Approve invoice",
"risk_level": "high",
"audit_default": true
}'

For Core-managed resources, use the internal resources table mapping:

Terminal window
curl -s -X POST "$PLYSTRA_URL/api/v1/resource-types/invoice/mapping" \
-H "Authorization: Bearer $PLYSTRA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "rm_invoice",
"storage_kind": "internal_table",
"table_name": "resources",
"id_field": "id",
"space_field": "space_id",
"group_field": "group_id",
"owner_member_field": "owner_member_id",
"visibility_field": "visibility",
"metadata_field": "metadata",
"status": "active"
}'
Terminal window
curl -s -X POST "$PLYSTRA_URL/api/v1/spaces" \
-H "Authorization: Bearer $PLYSTRA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "space_acme",
"name": "Acme",
"slug": "acme",
"type": "customer",
"status": "active"
}'
Terminal window
curl -s -X POST "$PLYSTRA_URL/api/v1/spaces/space_acme/groups" \
-H "Authorization: Bearer $PLYSTRA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "group_finance",
"name": "Finance",
"path": "finance"
}'
curl -s -X POST "$PLYSTRA_URL/api/v1/spaces/space_acme/groups" \
-H "Authorization: Bearer $PLYSTRA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "group_finance_apac",
"parent_group_id": "group_finance",
"name": "APAC",
"path": "finance.apac"
}'

Create a User:

Terminal window
curl -s -X POST "$PLYSTRA_URL/api/v1/users" \
-H "Authorization: Bearer $PLYSTRA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "user_alice",
"email": "[email protected]",
"password": "plystra-demo",
"status": "active"
}'

Create a Member in the Space:

Terminal window
curl -s -X POST "$PLYSTRA_URL/api/v1/spaces/space_acme/members" \
-H "Authorization: Bearer $PLYSTRA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "member_finance_reviewer",
"display_name": "Finance Reviewer",
"member_type": "human",
"status": "active"
}'

Bind the User to the Member:

Terminal window
curl -s -X POST "$PLYSTRA_URL/api/v1/spaces/space_acme/user-members" \
-H "Authorization: Bearer $PLYSTRA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "um_alice_finance_reviewer",
"user_id": "user_alice",
"member_id": "member_finance_reviewer",
"relation_type": "login",
"is_primary": true,
"status": "active"
}'

Create a Permission:

Terminal window
curl -s -X POST "$PLYSTRA_URL/api/v1/permissions" \
-H "Authorization: Bearer $PLYSTRA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "perm_invoice_approve_group_tree",
"resource": "invoice",
"action": "approve",
"scope": "group_tree",
"description": "Approve invoices within a group subtree"
}'

Create a Role:

Terminal window
curl -s -X POST "$PLYSTRA_URL/api/v1/spaces/space_acme/roles" \
-H "Authorization: Bearer $PLYSTRA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "role_finance_approver",
"key": "finance_approver",
"name": "Finance Approver"
}'

Attach the Permission to the Role:

Terminal window
curl -s -X POST "$PLYSTRA_URL/api/v1/role-permissions" \
-H "Authorization: Bearer $PLYSTRA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "rp_finance_approver_invoice_approve",
"role_id": "role_finance_approver",
"permission_id": "perm_invoice_approve_group_tree"
}'

Grant the Role to the Member, anchored at group_finance:

Terminal window
curl -s -X POST "$PLYSTRA_URL/api/v1/spaces/space_acme/member-roles" \
-H "Authorization: Bearer $PLYSTRA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "mr_finance_reviewer_approver",
"member_id": "member_finance_reviewer",
"role_id": "role_finance_approver",
"scope_anchor_group_id": "group_finance",
"status": "active"
}'
Terminal window
curl -s -X POST "$PLYSTRA_URL/api/v1/resources" \
-H "Authorization: Bearer $PLYSTRA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "invoice_001",
"space_id": "space_acme",
"resource_type": "invoice",
"external_id": "billing-system-invoice-001",
"group_id": "group_finance_apac",
"owner_member_id": "member_finance_reviewer",
"display_name": "Invoice 001",
"visibility": "private",
"status": "active"
}'

Using an API key:

Terminal window
curl -s -X POST "$PLYSTRA_URL/api/v1/authz/check" \
-H "X-Plystra-API-Key: $PLYSTRA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"actor": {
"user_id": "user_alice",
"member_id": "member_finance_reviewer",
"user_member_id": "um_alice_finance_reviewer",
"space_id": "space_acme"
},
"resource_type": "invoice",
"resource_id": "invoice_001",
"action": "approve"
}'

Using a Bearer access token and the session active actor:

Terminal window
curl -s -X POST "$PLYSTRA_URL/api/v1/authz/check" \
-H "Authorization: Bearer $PLYSTRA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"resource_type": "invoice",
"resource_id": "invoice_001",
"action": "approve"
}'

An allow response has data.decision equal to allow. A deny response still returns a decision object when the request is valid, with decision = deny and a deny_code.