DatabasePermissionService

works.iterative.sqldb.DatabasePermissionService
See theDatabasePermissionService companion object
case class DatabasePermissionService(repository: PermissionRepository, config: PermissionConfig) extends PermissionService, EnumerablePermissionService, MutablePermissionService

Database-backed implementation of PermissionService with fail-closed error handling.

This implementation provides production-ready permission storage that:

  • Persists RelationTuples to a SQL database via PermissionRepository
  • Delegates permission logic to PermissionLogic (pure domain logic)
  • Implements fail-closed pattern: database errors result in access denial (return false)
  • Logs infrastructure failures before denying access for debugging

SECURITY CRITICAL: Database errors must NEVER bypass authorization checks. The fail-closed pattern ensures that any infrastructure failure (database down, connection timeout, query error) results in access denial rather than granting unintended permissions.

Value parameters

config

Permission configuration defining inheritance rules

repository

The repository for persisting relation tuples

Attributes

Companion
object
Graph
Supertypes
trait Serializable
trait Product
trait Equals
trait MutablePermissionService
trait EnumerablePermissionService
trait PermissionService
class Object
trait Matchable
class Any
Show all

Members list

Value members

Concrete methods

def grantPermission(userId: UserId, relation: String, target: PermissionTarget): UIO[Boolean]

Grant a permission relation to a user.

Grant a permission relation to a user.

Persists the relation tuple to the database via repository.addRelation. The repository implementation should be idempotent (duplicate grants succeed).

Value parameters

relation

The permission relation

target

The permission target

userId

The user to grant the permission to

Attributes

Returns

UIO[Boolean] - true if successful, false if failed

def isAllowed(subj: Option[UserInfo], action: PermissionOp, obj: PermissionTarget): UIO[Boolean]

Check if a user is allowed to perform an action on a target resource.

Check if a user is allowed to perform an action on a target resource.

This method:

  1. Fetches all relation tuples for the user in the target's namespace 2. Delegates to PermissionLogic.isAllowed (pure function) 3. Returns false (fail-closed) if any database error occurs 4. Logs warnings when database errors prevent permission checks

Value parameters

action

The permission operation to check

obj

The target resource

subj

The user information (optional)

Attributes

Returns

UIO[Boolean] - true if allowed, false if denied or error (fail-closed)

def listAllowed(subj: UserInfo, action: PermissionOp, namespace: String): UIO[Set[String]]

List all resource IDs in a namespace that the user is allowed to access.

List all resource IDs in a namespace that the user is allowed to access.

This method fetches all relation tuples for the user in the namespace, then delegates to PermissionLogic.listAllowed to compute accessible resources.

On database error, returns empty set (fail-closed).

Value parameters

action

The permission operation

namespace

The resource namespace to search

subj

The user information

Attributes

Returns

UIO[Set[String]] - Set of accessible resource IDs

def revokePermission(userId: UserId, relation: String, target: PermissionTarget): UIO[Boolean]

Revoke a permission relation from a user.

Revoke a permission relation from a user.

Removes the relation tuple from the database via repository.removeRelation. The repository implementation should be idempotent (revoking non-existent relations succeeds).

Value parameters

relation

The permission relation to revoke

target

The permission target

userId

The user to revoke the permission from

Attributes

Returns

UIO[Boolean] - true if successful, false if failed

Inherited methods

def isAllowed(subj: UserInfo, action: PermissionOp, obj: PermissionTarget): UIO[Boolean]

Attributes

Inherited from:
PermissionService
def productElementNames: Iterator[String]

Attributes

Inherited from:
Product
def productIterator: Iterator[Any]

Attributes

Inherited from:
Product