Start HereOrdered learning track

Access Control Taxonomy: RBAC, ABAC, ReBAC, PBAC, ACL, Capabilities

Learn Java Authorization Pattern - Part 002

A production-grade taxonomy of access control models for Java systems: RBAC, ABAC, ReBAC, PBAC, ACL, capabilities, scopes, and hybrid authorization.

16 min read3142 words
PrevNext
Lesson 0240 lesson track01–08 Start Here
#java#authorization#access-control#rbac+5 more

Access Control Taxonomy: RBAC, ABAC, ReBAC, PBAC, ACL, Capabilities

Part sebelumnya membangun primitive:

subject + action + resource + context -> decision

Sekarang kita akan membahas berbagai model access control. Tujuannya bukan menghafal akronim. Tujuannya adalah memilih model yang tepat untuk masalah yang tepat.

Di sistem Java enterprise, authorization yang baik hampir tidak pernah murni satu model. Biasanya ia hybrid:

RBAC untuk coarse capability.
ABAC untuk condition dan policy constraint.
ReBAC untuk object relationship.
ACL untuk explicit sharing kecil.
Scope untuk delegated API access.
Policy-as-code untuk governability dan audit.
Database/query scoping untuk data-level enforcement.

Kesalahan besar adalah memilih model karena populer, bukan karena cocok dengan domain.


1. Peta Besar Access Control

Quick intuition:

ModelPertanyaan UtamaCocok Untuk
RBACRole apa yang dimiliki subject?organisasi, job function, coarse permission
ABACAtribut apa yang cocok dengan policy?contextual, dynamic, compliance-heavy rules
ReBACRelasi apa yang menghubungkan subject dan object?sharing, hierarchy, ownership graph
PBACPolicy apa yang berlaku?centralized governance, audit, externalized rules
ACLSiapa yang secara eksplisit ada di list resource?document/file sharing sederhana
CapabilityToken/handle apa yang memberikan authority?temporary delegated access, signed URL
ScopeClient/token diberi delegated authority apa?OAuth/API integration
MACLabel/classification apa yang wajib dipatuhi?high-security/classified environments
DACOwner resource boleh memberi akses ke siapa?collaborative apps, owner-managed sharing

2. RBAC: Role-Based Access Control

RBAC menjawab:

Apakah subject memiliki role yang memiliki permission untuk action ini?

Model dasar:

NIST/Sandhu RBAC model menekankan bahwa permission diasosiasikan dengan role, dan user di-assign ke role. Ini menyederhanakan manajemen permission karena perubahan job function bisa dilakukan lewat role assignment, bukan assign permission satu per satu ke user.

2.1 RBAC Primitive

User/Subject
Role
Permission
Session
User-Role Assignment
Permission-Role Assignment
Role Hierarchy
Constraints

Contoh:

Role: CASE_INVESTIGATOR
Permissions:
- case.viewAssigned
- case.addEvidence
- case.submitForReview

Role: CASE_SUPERVISOR
Permissions:
- case.viewTeam
- case.approve
- case.reject
- case.assignInvestigator

Role: LEGAL_REVIEWER
Permissions:
- case.viewLegalAssessment
- case.approveLegalPosition

2.2 RBAC di Java

Model sederhana:

public record Role(String name) {}
public record Permission(String name) {}

public interface RoleRepository {
    Set<Role> findRolesBySubject(String subjectId, String tenantId);
}

public interface PermissionRepository {
    Set<Permission> findPermissionsByRoles(Set<Role> roles, String tenantId);
}

public final class RbacAuthorizer {
    private final RoleRepository roleRepository;
    private final PermissionRepository permissionRepository;

    public RbacAuthorizer(
        RoleRepository roleRepository,
        PermissionRepository permissionRepository
    ) {
        this.roleRepository = roleRepository;
        this.permissionRepository = permissionRepository;
    }

    public boolean hasPermission(Subject subject, String permissionName) {
        Set<Role> roles = roleRepository.findRolesBySubject(subject.id(), subject.tenantId());
        Set<Permission> permissions = permissionRepository.findPermissionsByRoles(roles, subject.tenantId());
        return permissions.contains(new Permission(permissionName));
    }
}

Ini cukup untuk coarse-grained gate:

if (!rbacAuthorizer.hasPermission(subject, "case.approve")) {
    throw new AccessDeniedException("AUTHZ_MISSING_PERMISSION");
}

Tetapi belum cukup untuk object-level rule:

Supervisor boleh approve hanya case yang assigned ke dia.
Submitter tidak boleh approve case miliknya sendiri.
Supervisor tenant A tidak boleh approve case tenant B.

2.3 Kapan RBAC Cocok

RBAC cocok ketika:

  • struktur organisasi cukup stabil;
  • permission mengikuti job function;
  • admin ingin mengelola akses via role;
  • policy tidak terlalu bergantung pada object relationship;
  • audit butuh menjawab user punya role apa saat action terjadi;
  • banyak endpoint memerlukan coarse-grained capability.

Contoh:

Only users with REPORT_VIEWER can access reporting module.
Only CASE_SUPERVISOR can see approval queue.
Only USER_ADMIN can invite new employee.

2.4 Kapan RBAC Gagal

RBAC gagal ketika pertanyaan sebenarnya object-specific atau context-specific.

Contoh gagal:

Can Alice view Bob's document?
Can investigator A edit case X?
Can supervisor approve case submitted by their own team member?
Can auditor export only cases in assigned jurisdiction?

Kalau dipaksa memakai role, muncul role explosion:

CASE_SUPERVISOR_REGION_JAKARTA_HIGH_RISK_LEVEL_3
CASE_SUPERVISOR_REGION_BANDUNG_LOW_RISK_LEVEL_2
CASE_SUPERVISOR_TENANT_A_DEPARTMENT_ENFORCEMENT

Ini tanda modelnya salah.

2.5 RBAC Failure Modes

Failure ModeGejalaSolusi
Role explosionrole terlalu banyak dan spesifikpindahkan condition ke ABAC/ReBAC
Hidden superadminADMIN bypass semuaprivilege decomposition + audit
Permission driftrole berbeda antar servicecentral permission registry
Tenant leakagerole global dipakai untuk tenant-local datatenant-scoped role assignment
Stale rolerevoke tidak langsung efektifshort TTL, cache invalidation, authoritative check
UI-only role checktombol disembunyikan tapi API terbukaserver-side enforcement

3. ABAC: Attribute-Based Access Control

ABAC menjawab:

Apakah atribut subject, resource, action, dan environment memenuhi policy?

NIST SP 800-162 mendeskripsikan ABAC sebagai model logical access control yang mengevaluasi rules terhadap attributes dari subject, object/resource, operation/action, dan environment.

Contoh atribut:

KategoriContoh
Subjectdepartment, clearance, employment status, role, jurisdiction
Resourceowner, tenant, classification, status, risk level
Actionaction name, risk tier, read/write, bulk/single
Environmenttime, device trust, IP range, MFA level, channel

3.1 ABAC Policy Example

Allow case.approve if:
- subject.department == resource.ownerDepartment
- subject.clearance >= resource.requiredClearance
- resource.status == UNDER_REVIEW
- action.riskTier in [HIGH, CRITICAL] implies context.mfaLevel >= 2
- subject.id != resource.submittedBy

Java local evaluator:

public final class AbacCaseApprovalPolicy implements AuthorizationPolicy {

    @Override
    public AuthorizationDecision evaluate(AuthorizationRequest request) {
        if (!"case.approve".equals(request.action().name())) {
            return AuthorizationDecision.notApplicable("ABAC_CASE_APPROVAL_NOT_APPLICABLE");
        }

        String subjectDepartment = (String) request.subject().attributes().get("department");
        String ownerDepartment = (String) request.resource().attributes().get("ownerDepartment");
        if (!subjectDepartment.equals(ownerDepartment)) {
            return AuthorizationDecision.deny(
                "AUTHZ_DEPARTMENT_MISMATCH",
                "Subject department does not match resource owner department"
            );
        }

        int subjectClearance = (int) request.subject().attributes().get("clearance");
        int requiredClearance = (int) request.resource().attributes().get("requiredClearance");
        if (subjectClearance < requiredClearance) {
            return AuthorizationDecision.deny(
                "AUTHZ_INSUFFICIENT_CLEARANCE",
                "Subject clearance is lower than required resource clearance"
            );
        }

        String submittedBy = (String) request.resource().attributes().get("submittedBy");
        if (request.subject().id().equals(submittedBy)) {
            return AuthorizationDecision.deny(
                "AUTHZ_MAKER_CHECKER_VIOLATION",
                "Subject cannot approve their own submission"
            );
        }

        Integer mfaLevel = (Integer) request.context().values().getOrDefault("mfaLevel", 0);
        if (request.action().riskTier().isHighOrCritical() && mfaLevel < 2) {
            return AuthorizationDecision.deny(
                "AUTHZ_MFA_REQUIRED",
                "High-risk action requires MFA level 2"
            );
        }

        return AuthorizationDecision.allow(
            "AUTHZ_ABAC_POLICY_ALLOWED",
            "ABAC conditions matched"
        );
    }
}

3.2 Kapan ABAC Cocok

ABAC cocok ketika:

  • decision bergantung pada banyak atribut;
  • policy sering berubah;
  • compliance rule penting;
  • resource punya classification atau lifecycle state;
  • akses bergantung pada waktu, lokasi, device, risk;
  • tenant/jurisdiction/department boundaries kompleks;
  • role saja menyebabkan role explosion.

Contoh:

Only reviewers in the same jurisdiction can view high-risk case evidence.
Payment approval above 1B requires clearance level 4 and MFA.
Customer support can view customer data only with active support ticket.
Reports marked confidential require managed device and audit purpose.

3.3 ABAC Failure Modes

Failure ModeGejalaSolusi
Attribute sprawlterlalu banyak atribut tanpa ownershipattribute catalog + source of truth
Stale attributesdecision memakai claim lamafreshness policy
Null ambiguitymissing attribute dianggap cocokexplicit missing semantics
Policy opacitysulit tahu kenapa denyreason code + explainability
Performance issuesemua request load banyak dataattribute minimization + cache
Inconsistent attribute namesdept, department, orgUnit campurcanonical schema

3.4 ABAC Tidak Berarti Semua Harus Dynamic

Jangan mengubah setiap permission menjadi expression rumit.

Buruk:

allow if subject.role contains x and subject.attrA == y and resource.attrB != z and ...

Lebih baik:

RBAC: user has capability case.approve
ABAC: action allowed only if case.status == UNDER_REVIEW and subject.clearance >= requiredClearance
ReBAC: subject must be assigned supervisor of the case

Hybrid lebih mudah diaudit daripada satu expression raksasa.


4. ReBAC: Relationship-Based Access Control

ReBAC menjawab:

Apakah ada relationship yang membuat subject berhak terhadap resource?

Contoh:

Alice can view document D because:
- Alice is member of team T;
- Team T is viewer of folder F;
- Document D is inside folder F.

ReBAC sangat cocok untuk sharing, ownership, hierarchy, nested resources, org graph, folder/document model, project membership, team-based access, dan delegated relationships.

4.1 Tuple Model

Banyak ReBAC system memakai tuple:

object#relation@user

Contoh:

case:CASE-1#owner@user:alice
case:CASE-1#assignee@user:bob
case:CASE-1#supervisor@user:carol
folder:F1#viewer@team:investigation
team:investigation#member@user:dina
document:D1#parent@folder:F1

Question:

Is user:dina a viewer of document:D1?

Engine menelusuri relationship graph.

4.2 Zanzibar-Style Authorization

Google Zanzibar memperkenalkan model authorization global berbasis relationship tuple dan userset rewrite. Paper Zanzibar membahas authorization untuk banyak produk Google dengan konsistensi, relationship graph, namespace config, tuple store, dan check API.

Konsep utama:

namespace/type
object
relation
userset
tuple
rewrite rule
check
expand
consistency token

Sederhana:

viewer = owner OR editor OR parent.viewer
editor = owner OR direct_editor

4.3 OpenFGA Style Model

OpenFGA adalah sistem fine-grained authorization yang terinspirasi Zanzibar. Konsep dasarnya: authorization model + relationship tuples + check/list APIs.

Contoh model konseptual:

type user

type team
  relations
    define member: [user]

type case
  relations
    define owner: [user]
    define assignee: [user]
    define supervisor: [user]
    define viewer: owner or assignee or supervisor

Java application tidak perlu menghitung graph sendiri. Ia bertanya:

check(user:alice, relation=viewer, object=case:CASE-1)

4.4 Kapan ReBAC Cocok

ReBAC cocok ketika:

  • access ditentukan oleh relationship, bukan hanya role;
  • object memiliki parent/child hierarchy;
  • sharing eksplisit diperlukan;
  • user bisa tergabung dalam team/group/project;
  • permission diwariskan dari parent object;
  • list objects user can access penting;
  • domain memiliki graph alami.

Contoh:

User can view case if assigned to case.
User can view document if member of team that owns folder containing document.
User can approve quote if manager of salesperson who owns quote.
User can access workspace if member of organization that owns workspace.

4.5 ReBAC Failure Modes

Failure ModeGejalaSolusi
Graph explosiontraversal mahalbounded depth + indexing + caching
Stale relationshipsrevoked sharing masih berlakuconsistency token/watch/invalidation
Modeling confusionrelation terlalu abstrakdomain-specific relation names
Cyclesrecursive relation tak terkendalimodel validation
List performancecheck satu-satu untuk ribuan objectlist objects API/query integration
Split brainDB relation dan authz tuple tidak sinkrontransactional outbox/saga repair

5. PBAC: Policy-Based Access Control

PBAC menjawab:

Policy mana yang berlaku dan apa hasil evaluasinya?

PBAC bukan model data tunggal seperti RBAC atau ReBAC. PBAC adalah pendekatan: authorization logic diekspresikan sebagai policy yang bisa dikelola, dites, di-version, diaudit, dan sering kali dievaluasi oleh engine khusus.

Contoh tools/approach:

OPA/Rego
Cedar/Amazon Verified Permissions
XACML-style PDP/PEP architecture
Custom internal policy engine
Spring AuthorizationManager composition

5.1 Policy as Code

OPA memosisikan dirinya sebagai policy engine untuk mengelola policy di berbagai stack. Dengan OPA, policy ditulis dalam Rego dan aplikasi mengirim input untuk mendapat decision.

Cedar adalah policy language untuk menulis authorization policies dan membuat authorization decisions. Amazon Verified Permissions memakai Cedar sebagai managed authorization service. Cedar memisahkan principal, action, resource, dan context.

5.2 Kapan PBAC Cocok

PBAC cocok ketika:

  • policy sering berubah tanpa deploy aplikasi;
  • security/compliance team ikut mengelola policy;
  • butuh audit policy version;
  • banyak service harus konsisten;
  • butuh shadow evaluation/canary policy;
  • authorization rules kompleks tetapi harus explainable;
  • ingin memisahkan policy decision dari business implementation.

5.3 PBAC Failure Modes

Failure ModeGejalaSolusi
Policy divorced from domainPDP tidak punya data domaininput contract + PIP design
Latencycall PDP tiap request mahallocal sidecar/cache/bundle
Fail-openPDP timeout dianggap allowfail-closed policy
Policy driftapp dan policy beda makna actionaction/resource registry
Weak testingpolicy berubah tanpa regressionpolicy unit + golden tests
Poor explainabilitydeny tidak jelasreason code + decision log

6. ACL: Access Control List

ACL menjawab:

Apakah subject ada dalam daftar akses resource ini?

Contoh:

document:DOC-1 ACL:
- user:alice -> owner
- user:bob -> editor
- team:legal -> viewer

ACL mudah dipahami dan cocok untuk resource yang memang dibagikan secara eksplisit.

6.1 ACL Table Design

create table document_acl (
    document_id uuid not null,
    subject_type varchar(32) not null,
    subject_id varchar(128) not null,
    permission varchar(64) not null,
    granted_by varchar(128) not null,
    granted_at timestamp not null,
    expires_at timestamp null,
    primary key (document_id, subject_type, subject_id, permission)
);

Java check:

public boolean canViewDocument(Subject subject, UUID documentId) {
    return documentAclRepository.exists(
        documentId,
        subject.type().name(),
        subject.id(),
        "viewer"
    );
}

6.2 Kapan ACL Cocok

ACL cocok ketika:

  • resource punya daftar eksplisit user/group yang boleh akses;
  • sharing manual penting;
  • jumlah subject per resource relatif kecil;
  • inheritance sederhana atau tidak ada;
  • audit grant/revoke penting.

Contoh:

shared document
case evidence shared to external counsel
temporary access to report
project-specific invite list

6.3 Kapan ACL Tidak Cocok

ACL bermasalah ketika:

  • inheritance kompleks;
  • perlu group nesting;
  • resource jutaan dan list besar;
  • query list all accessible objects harus cepat;
  • sharing mengikuti org hierarchy;
  • ACL perlu condition dinamis.

Di titik itu, ReBAC biasanya lebih kuat.


7. Capability-Based Access Control

Capability-based access menjawab:

Apakah caller memiliki capability/token/handle yang memberi authority untuk action ini?

Contoh umum:

pre-signed URL untuk download file
one-time token untuk reset password
temporary upload token
invitation link
magic link
limited-use API key

Capability biasanya membawa authority di token itu sendiri atau di handle yang bisa divalidasi server.

7.1 Capability Example

Download evidence file:
- token berlaku 5 menit;
- token terikat ke document ID;
- token terikat ke action document.download;
- token terikat ke subject atau session;
- token single-use atau limited-use;
- token bisa direvokasi.

Java-style validation:

public record DownloadCapability(
    String tokenId,
    String subjectId,
    String resourceType,
    String resourceId,
    String action,
    Instant expiresAt,
    boolean singleUse
) {}

public void verifyCapability(DownloadCapability cap, Subject subject, String documentId) {
    if (Instant.now().isAfter(cap.expiresAt())) {
        throw new AccessDeniedException("AUTHZ_CAPABILITY_EXPIRED");
    }
    if (!cap.subjectId().equals(subject.id())) {
        throw new AccessDeniedException("AUTHZ_CAPABILITY_SUBJECT_MISMATCH");
    }
    if (!cap.resourceId().equals(documentId)) {
        throw new AccessDeniedException("AUTHZ_CAPABILITY_RESOURCE_MISMATCH");
    }
    if (!"document.download".equals(cap.action())) {
        throw new AccessDeniedException("AUTHZ_CAPABILITY_ACTION_MISMATCH");
    }
}

7.2 Capability Failure Modes

Failure ModeRisikoMitigasi
Token terlalu lamaleak menjadi akses panjangshort TTL
Token tidak resource-bounddipakai untuk object lainbind resource ID
Token tidak subject-boundlink bisa dipakai siapa sajabind subject/session jika perlu
Tidak revocablesulit cabut aksesserver-side token registry
Log leaktoken muncul di log/referrerjangan taruh secret di URL jika tidak perlu
Overbroad capabilitysatu token untuk banyak aksileast privilege capability

8. OAuth/API Scopes

Scope menjawab:

Client/token ini diberi delegated authority apa?

Scope sering muncul pada OAuth2 access token:

orders:read
orders:write
cases:read
cases:approve
reports:export

Scope penting, tetapi jangan disalahpahami.

Scope biasanya membatasi client/delegation, bukan menggantikan object-level authorization.

Contoh:

Token punya scope cases:read.
Artinya client boleh meminta read case.
Belum berarti user boleh membaca semua case.

Server tetap harus mengecek:

scope allows action?
AND subject allowed on resource instance?
AND context policy satisfied?

8.1 Scope + RBAC + Object Authz

8.2 Scope Failure Modes

Failure ModeContoh
Scope dianggap final authorizationcases:read membaca semua case
Scope terlalu kasaradmin scope di semua API
Scope tidak audience-boundtoken service A dipakai service B
Scope tidak tenant-boundtoken tenant A dipakai untuk tenant B
Scope tidak action-specificwrite mencakup approve/delete/export

9. DAC dan MAC

9.1 DAC: Discretionary Access Control

DAC berarti owner/resource controller bisa memberikan akses.

Contoh:

Owner document membagikan document ke user lain.
Project owner invite member.
Case owner grants external counsel temporary view.

DAC sering diimplementasikan dengan ACL atau ReBAC.

Risiko DAC:

  • owner memberi akses terlalu luas;
  • privilege propagation sulit dikontrol;
  • sharing tidak sesuai compliance;
  • akses lama tidak dicabut.

Solusi:

  • policy guard terhadap grant action;
  • expiration;
  • approval untuk sensitive resource;
  • access review;
  • audit grant/revoke.

9.2 MAC: Mandatory Access Control

MAC memakai label/classification yang wajib dipatuhi. User tidak bebas membagikan akses jika label melarang.

Contoh:

resource.classification = SECRET
subject.clearance >= SECRET required
no write-down from high classification to low classification

MAC cocok untuk high-security domain, classified information, legal hold, sealed evidence, atau regulatory documents.

Dalam enterprise Java biasa, MAC sering muncul sebagai subset ABAC:

allow if subject.clearance >= resource.classificationLevel

10. Comparison Matrix

ModelStrengthWeaknessJava Implementation Style
RBACmudah dipahami, admin-friendlyrole explosion, object-level lemahrole/permission tables, Spring authorities
ABACfleksibel, context-awareattribute governance sulitpolicy evaluator, OPA/Cedar, custom engine
ReBACkuat untuk relationship graphgraph complexity, consistencyOpenFGA/Zanzibar-style service, tuple store
PBACgovernance, versioning, auditmembutuhkan policy lifecycleOPA/Cedar/custom PDP
ACLsederhana untuk explicit sharingsulit scale/inheritanceACL table per resource
Capabilitybagus untuk temporary delegationleak/revocation risksigned token/server-side capability registry
Scopestandar untuk API delegationbukan object authzOAuth2 resource server checks
MACkuat untuk classificationrigidlabels + clearance policy
DACuser-managed sharingover-sharing riskACL/ReBAC + grant policy

11. How to Choose: Decision Tree

Rule praktis:

Start simple, but do not start wrong.

Kalau domainnya jelas object-relationship-heavy, jangan mulai dengan role-only model. Kamu akan membayar migration cost besar.


12. Hybrid Authorization: Model yang Umum di Production

Contoh hybrid untuk regulatory case management:

RBAC:
- CASE_INVESTIGATOR can submit case for review.
- CASE_SUPERVISOR can approve case.
- LEGAL_REVIEWER can review legal assessment.

ABAC:
- subject.clearance must be >= case.requiredClearance.
- case.status must be UNDER_REVIEW before approval.
- high-risk approval requires MFA level 2.

ReBAC:
- subject must be assigned investigator/supervisor of case.
- subject can view case if member of case team.

PBAC:
- policy stored/versioned centrally.
- decision logged with policy version.

ACL:
- external counsel can view specific evidence package.

Capability:
- temporary signed URL for evidence download.

Scope:
- API client must have cases:read or cases:approve scope.

Pipeline:


13. Model by Domain Shape

13.1 Admin Console

Typical model:

RBAC + SoD constraints + audit

Why:

  • admin action follows job function;
  • privileged action needs strong audit;
  • separation of duties matters.

13.2 Document Sharing

Typical model:

ReBAC + ACL + capability links

Why:

  • document/folder hierarchy;
  • team membership;
  • explicit sharing;
  • temporary download links.

13.3 Payment Approval

Typical model:

RBAC + ABAC + maker-checker + risk policy

Why:

  • role defines approver capability;
  • amount/currency/risk/region changes decision;
  • submitter cannot approve.

13.4 Multi-Tenant SaaS

Typical model:

tenant boundary + RBAC + ABAC + query scoping

Why:

  • tenant isolation is invariant;
  • roles are often tenant-local;
  • resource visibility must be scoped at query level.

13.5 Regulatory Case Management

Typical model:

RBAC + ABAC + ReBAC + workflow-state authorization + field-level authorization + audit

Why:

  • case assignment and team relationship;
  • classification/clearance;
  • state transition guard;
  • maker-checker;
  • sealed evidence;
  • regulatory audit.

14. Authorization Model Smells

14.1 Role Names Encode Resource Identity

CASE_123_VIEWER
TENANT_ABC_REPORT_ADMIN
PROJECT_X_EDITOR

Ini ReBAC/ACL problem yang dipaksa masuk RBAC.

14.2 Policy Requires 20 Token Claims

Kalau token harus membawa semua atribut, attribute freshness akan buruk. Ambil fakta mutable dari authoritative source.

14.3 Every Service Defines Permission Differently

Jika service A memakai case.approve, service B memakai approve_case, service C memakai CASE_APPROVER, audit dan governance rusak.

Butuh action registry.

14.4 Authorization Happens Only at Gateway

Gateway tidak tahu object instance dan workflow state. Gateway bagus untuk coarse gate, bukan satu-satunya enforcement.

14.5 Object Check in Controller, Search Query Unscoped

Endpoint detail aman, tetapi list/export bocor.

GET /cases/{id}       // checks object
GET /cases?status=x   // returns all tenant cases without assignment scope

List/search/export harus punya query scoping.


15. Java Architecture Patterns by Model

15.1 RBAC Package Structure

com.example.security.authz.rbac
├── Role.java
├── Permission.java
├── RoleRepository.java
├── PermissionRepository.java
├── RbacAuthorizationProvider.java
└── RoleAssignmentService.java

15.2 ABAC Package Structure

com.example.security.authz.abac
├── AttributeProvider.java
├── AttributeCatalog.java
├── Policy.java
├── PolicyEvaluator.java
├── Condition.java
└── AttributeResolutionException.java

15.3 ReBAC Package Structure

com.example.security.authz.relationship
├── RelationshipTuple.java
├── RelationshipWriter.java
├── RelationshipChecker.java
├── RelationshipModelRegistry.java
└── RelationshipSyncProcessor.java

15.4 PBAC Package Structure

com.example.security.authz.policy
├── PolicyDecisionPoint.java
├── PolicyEnforcementPoint.java
├── PolicyInformationPoint.java
├── PolicyAdministrationClient.java
├── DecisionLogSink.java
└── PolicyVersion.java

15.5 Common API

Terlepas dari model internal, application layer sebaiknya melihat API yang stabil:

public interface AuthorizationService {
    AuthorizationDecision authorize(AuthorizationRequest request);
    void verify(AuthorizationRequest request);
}

Jangan biarkan controller tahu apakah decision berasal dari RBAC table, ABAC evaluator, OPA, Cedar, atau OpenFGA.


16. Designing Permission Names

Permission/action names harus:

  • domain-specific;
  • stable;
  • tidak terlalu HTTP-oriented;
  • tidak terlalu technical;
  • bisa diaudit;
  • bisa dipetakan ke UI dan API;
  • bisa dipetakan ke policy engine.

Good:

case.view
case.search
case.submitForReview
case.approve
case.reject
case.assignInvestigator
case.exportEvidence
case.viewSealedEvidence
case.reopen

Bad:

GET_CASE
POST_APPROVE_ENDPOINT
WRITE_CASE
ADMIN_ACTION
MANAGE_CASE

Permission manage biasanya terlalu luas. Pecah menjadi action konkret.


17. Relationship Names

Relationship names harus merepresentasikan fakta domain, bukan implementation detail.

Good:

case#assignee@user:alice
case#supervisor@user:bob
case#legal_reviewer@user:carol
case#team@team:enforcement-alpha
team#member@user:dina
folder#parent@case:CASE-1
document#parent@folder:F1

Bad:

case#allowed@user:alice
object#access@user:bob
resource#thing@group:x

Semakin jelas relation, semakin mudah policy dan audit.


18. Attribute Catalog

ABAC membutuhkan attribute catalog.

Contoh:

AttributeOwnerSourceFreshnessTypeRequired For
subject.departmentHR/IAMemployee service5 minstringcase view/approve
subject.clearanceIAM/securityclearance serviceimmediate for revokeintconfidential access
resource.classificationcase servicecase DBreal-timeenumfield redaction
resource.statuscase servicecase DBreal-timeenumworkflow transition
context.mfaLevelauthn/sessionsession storerequest-timeinthigh-risk action
context.requestPurposecaller/APIrequestrequest-timeenumaudit/support access

Tanpa catalog, ABAC berubah menjadi kumpulan string map yang rapuh.


19. Policy Combining

Jika ada banyak policy, bagaimana hasil digabung?

Common combining algorithms:

AlgorithmMakna
Deny overridessatu deny cukup untuk deny
Permit overridessatu allow cukup untuk allow
First applicablepolicy pertama yang match menang
Consensus/majorityjarang untuk authz app biasa
Explicit prioritypolicy priority menentukan hasil

Untuk high-security system, deny overrides sering lebih aman.

Contoh:

Policy A: CASE_SUPERVISOR may approve assigned case -> ALLOW
Policy B: submitter cannot approve own case -> DENY
Final: DENY

Kalau permit overrides, maker-checker bisa bocor.

Java skeleton:

public final class DenyOverridesCombiner {
    public AuthorizationDecision combine(List<AuthorizationDecision> decisions) {
        for (AuthorizationDecision decision : decisions) {
            if (decision.effect() == AuthorizationEffect.DENY) {
                return decision;
            }
        }

        for (AuthorizationDecision decision : decisions) {
            if (decision.effect() == AuthorizationEffect.ALLOW) {
                return decision;
            }
        }

        boolean hasIndeterminate = decisions.stream()
            .anyMatch(d -> d.effect() == AuthorizationEffect.INDETERMINATE);

        if (hasIndeterminate) {
            return AuthorizationDecision.deny(
                "AUTHZ_INDETERMINATE_DENIED",
                "At least one policy could not be evaluated"
            );
        }

        return AuthorizationDecision.deny(
            "AUTHZ_NO_APPLICABLE_POLICY",
            "No applicable policy allowed this request"
        );
    }
}

20. Migration Path: From Naive Role Checks to Mature Authorization

Banyak sistem Java mulai seperti ini:

@PreAuthorize("hasRole('ADMIN')")

Jangan langsung rewrite semua ke OPA/OpenFGA. Migration harus aman.

Step 1: Inventory Protected Actions

Buat daftar:

endpoint -> business action -> resource type -> current check -> risk

Step 2: Normalize Permission Names

Ubah dari:

ROLE_ADMIN
ROLE_USER
CAN_DO_THING

menjadi:

case.view
case.approve
document.download
report.export

Step 3: Introduce AuthorizationService Facade

Controller/service tidak lagi langsung cek role.

authorizationService.verify(request);

Step 4: Add Object-Level Checks

Mulai dari endpoint high-risk:

GET by id
PATCH by id
DELETE by id
approve/reject/cancel/export

Step 5: Add Query Scoping

Search/list/export harus scoped.

Step 6: Add Decision Logging

Simpan decision evidence untuk action high-risk.

Step 7: Externalize Policy jika Perlu

Pindah ke OPA/Cedar/OpenFGA ketika alasan governance, consistency, atau relationship complexity sudah kuat.


21. Testing Implications by Model

ModelTest Utama
RBACrole-permission matrix, missing permission, role hierarchy
ABACattribute boundary, null/missing attribute, stale attribute
ReBACrelationship graph, inheritance, cycle, revocation
PBACpolicy unit test, policy diff, shadow decision
ACLgrant/revoke, expiry, list accessible resources
Capabilityexpiry, subject binding, resource binding, replay
Scopeaudience, action mapping, delegated client boundary

Authorization test harus banyak negative test. Banyak tim hanya test allow path. Itu tidak cukup.

Contoh negative matrix:

same role but different tenant -> deny
same tenant but not assigned -> deny
assigned but wrong status -> deny
supervisor but submitter same user -> deny
legal reviewer but insufficient clearance -> deny
valid permission but missing MFA -> deny

22. Production Recommendation

Untuk kebanyakan Java enterprise system, baseline yang sehat:

1. Define canonical action/resource model.
2. Use RBAC for coarse capability.
3. Use object-level authorization for every resource instance access.
4. Use ABAC for context/state/classification constraints.
5. Use ReBAC for assignment, ownership, sharing, group/team hierarchy.
6. Use query scoping for list/search/export.
7. Use policy-as-code only when governance/scale justifies it.
8. Log decisions for high-risk actions.
9. Treat scopes as delegation boundary, not final authorization.
10. Deny by default.

23. Checklist Part 002

  • Apakah problem ini sebenarnya role-based, attribute-based, relationship-based, atau hybrid?
  • Apakah role mulai mengandung tenant/resource/context detail?
  • Apakah permission names business-oriented?
  • Apakah object-level authorization ada untuk detail endpoint?
  • Apakah list/search/export memakai query scope?
  • Apakah attribute source dan freshness jelas?
  • Apakah relationship graph disimpan authoritative?
  • Apakah token scope hanya dipakai sebagai delegation boundary?
  • Apakah capability token short-lived dan resource-bound?
  • Apakah policy combining jelas?
  • Apakah deny overrides digunakan untuk constraint kritis?
  • Apakah decision bisa diaudit?
  • Apakah migration path tidak memecahkan sistem sekaligus?

24. Kesimpulan

Tidak ada satu access control model yang menang untuk semua sistem.

RBAC bagus untuk job function, tetapi lemah untuk object relationship.

ABAC bagus untuk context dan condition, tetapi bisa menjadi chaos tanpa attribute governance.

ReBAC bagus untuk relationship graph, tetapi membawa kompleksitas graph consistency dan query performance.

PBAC bagus untuk governance dan audit, tetapi membutuhkan policy lifecycle yang disiplin.

ACL bagus untuk explicit sharing sederhana, tetapi sulit untuk inheritance kompleks.

Capability bagus untuk temporary delegated authority, tetapi harus short-lived, bound, dan revocable.

Scope penting untuk OAuth/API delegation, tetapi bukan pengganti object-level authorization.

Model production biasanya hybrid. Keahlian senior bukan memilih akronim paling canggih. Keahlian senior adalah membaca bentuk domain, memilih primitive yang tepat, dan menjaga invariant authorization tetap benar saat sistem tumbuh.

Part berikutnya akan memisahkan authorization dari authentication, identity, entitlement, consent, delegation, subscription, feature flag, dan data visibility. Ini penting karena banyak sistem gagal bukan karena tidak punya authorization, tetapi karena mencampur terlalu banyak konsep menjadi satu flag atau satu role.


References

Lesson Recap

You just completed lesson 02 in start here. Use the series map if you want to review the broader track, or continue directly into the next lesson while the context is still warm.

Continue The Track

Keep the momentum while the lesson is still fresh. Move backward for review or continue forward into the next concept.