Skip to main content
SLang security is built around the request @subject. A subject is the authenticated caller. You decide which entity represents a subject, which field identifies it, and which role paths grant permissions.

Subjects and Identity Fields

Mark an entity with subject when records of that entity can authenticate. Add identity <fieldName> to choose the login identifier field. The identity field must exist on the entity. SLang also includes @id as an identity field internally, so identity email means the runtime can connect a token subject back to the persisted user row.
enum MembershipRole
  values
    member
    admin
    owner

entity User
  subject
  identity email
  fields
    email: EMAIL
    displayName: TEXT?

entity Organization
  group @id
  fields
    name: TEXT

entity Membership
  role membershipRole
  fields
    membershipRole: MembershipRole := "member"

entity Project
  fields
    title: TEXT

relation User[memberships] 1 --- 0..* Membership[member]
relation Organization[memberships] 1 --- 0..* Membership[organization]
relation Organization[projects] 1 --- 0..* Project[organization]

permissions User->memberships->member
  "project:read"

permissions User->memberships->admin
  "project:read"
  "project:write"

permissions User->memberships->owner
  "project:read"
  "project:write"
  "member:manage"

action CurrentUser(): User
  body
    return @subject.entity

action UpdateCurrentUser(displayName?: TEXT): User
  body
    user := @subject.entity
    update user {
      displayName := displayName
    }
    return user

action ListProjects(organizationId: TEXT): Page<Project>
  body
    org := single Organization where @id == organizationId
    return pageOf Project where organization == org

trigger CurrentUser on HttpRequest
  endpoint GET /me
  auth
    @subject is @defined

trigger UpdateCurrentUser on HttpRequest
  endpoint PATCH /me
  arguments
    displayName := @request.body.displayName
  auth
    @subject is @defined

trigger ListProjects on HttpRequest
  endpoint GET /organizations/{organizationId}/projects
  arguments
    organizationId := @request.path.organizationId
  auth
    @subject can "project:read" in Organization(@request.path.organizationId)

Getting the User Entity

Use @subject.entity when action logic needs the persisted row for the authenticated subject. Common uses:
  • Return the current user from GET /me.
  • Update profile fields on the authenticated user.
  • Compare ownership with where owner == @subject.entity.
When assigning ownership on create, you can assign either owner := @subject.entity or owner := @subject when the relation field points at the subject entity. The runtime resolves the subject to the stored entity before writing.

Groups, Roles, and Permissions

Use group @id on an entity whose instances scope permissions, such as an Organization, Team, or Workspace. Use role <fieldName> on the entity that carries role membership. The role field must be a non-optional enum. In the example above, Membership.membershipRole is the role field. Permission statements start at a subject entity, traverse relation fields, and end at one role enum value: permissions User->memberships->admin That grants the listed permission strings to users whose memberships path resolves to a Membership with role admin.

Trigger Auth Rules

Trigger auth blocks support these predicates:
  • @subject is @defined for any authenticated subject.
  • @subject is @anonymous for anonymous callers.
  • @subject is admin for a role by name.
  • @subject is admin in Organization(@request.path.organizationId) for a role scoped to a group instance.
  • @subject can "project:read" for a global permission.
  • @subject can "project:read" in Organization(@request.path.organizationId) for a permission scoped to a group instance.
You can combine predicates with and and or. Parenthesized auth subexpressions are not supported by current validation, so write combined rules without parentheses. If a trigger omits auth, it is public.

Generated Auth Endpoints

When a SLang app defines a subject with an identity field, the generated app exposes standard auth endpoints for that subject model:
  • POST /register
  • POST /login
  • POST /refresh
  • GET /.well-known/jwks.json
Registration and login accept identity and password. The identity value should match the field declared by identity <fieldName>, such as the user’s email address.