CISSP-114 · Lesson 8 of 12 · 27 min

Implementing authorization: RBAC, ABAC and privileged access

Choosing an access control model is the start; making it work across hundreds of applications, thousands of people and constant change is the hard part. Sub-domain 5.4 asks you to implement and manage authorization mechanisms. This lesson looks at the architecture of policy-based authorization, how role-based and attribute-based approaches are combined in practice, how separation of duties is enforced and tested, how cloud policies are evaluated and, most importantly, how privileged access is controlled, because administrator accounts are the keys attackers most want.

The authorization architecture

Modern authorization systems separate the decision from the enforcement. The policy enforcement point, PEP, sits in front of the resource, intercepts each request and enforces the decision; it might be an API gateway, an application component, a database proxy or an operating system kernel. The policy decision point, PDP, evaluates the request against policy and returns permit or deny, sometimes with obligations such as log this access or mask these fields. The policy information point, PIP, supplies attributes the PDP needs, such as the user's department from the directory or the device's compliance status from endpoint management. The policy administration point, PAP, is where policies are written, reviewed and versioned. This vocabulary comes from XACML, the OASIS eXtensible Access Control Markup Language, and is reused in NIST's ABAC guidance and in zero trust architectures, where the PDP becomes the policy engine and policy administrator, and the PEP the gateway in front of each resource.

Diagram: a user request arrives at the policy enforcement point in front of a resource. The PEP asks the policy decision point for a decision. The PDP reads policies from the policy administration point and attributes from policy information points: the directory for user attributes, the device management system for device health and a data catalog for resource classification. The PDP returns permit or deny with obligations; the PEP enforces and logs.
Policy-based authorization: the PEP enforces, the PDP decides using policies from the PAP and attributes from PIPs.

Separating decision from enforcement lets an organization write policy once and apply it consistently across many applications, test and version policies like code, and audit decisions centrally. Policy-as-code tools such as Open Policy Agent with its Rego language, or Amazon's Cedar language, express authorization rules in files that live in version control and pass through code review and automated tests. The risk is that the PDP becomes a critical dependency: if it is unavailable, PEPs must fail closed for sensitive resources, which needs high availability, caching with short lifetimes and clear failure rules.

A small ABAC policy decision point: explicit deny overrides permit, and anything not permitted is denied by default.
policies = [
    {'id': 'P1', 'effect': 'permit', 'action': 'read', 'when': lambda s, r, e: s['dept'] == r['dept'] and s['training_days'] <= 365},
    {'id': 'P2', 'effect': 'permit', 'action': 'update', 'when': lambda s, r, e: 'records-officer' in s['roles'] and s['dept'] == r['dept'] and e['device_managed']},
    {'id': 'P3', 'effect': 'deny', 'action': '*', 'when': lambda s, r, e: r['classification'] == 'restricted' and not e['device_managed']},
]
def decide(subject, resource, action, env):
    matched = [p for p in policies if p['action'] in (action, '*') and p['when'](subject, resource, env)]
    if any(p['effect'] == 'deny' for p in matched):
        return 'deny (' + ','.join(p['id'] for p in matched if p['effect'] == 'deny') + ')'
    if any(p['effect'] == 'permit' for p in matched):
        return 'permit (' + ','.join(p['id'] for p in matched) + ')'
    return 'deny (default)'
ana = {'dept': 'claims', 'roles': ['adjuster'], 'training_days': 120}
raj = {'dept': 'claims', 'roles': ['records-officer'], 'training_days': 400}
file_ = {'dept': 'claims', 'classification': 'restricted'}
for who, s in (('ana', ana), ('raj', raj)):
    for action in ('read', 'update'):
        for managed in (True, False):
            print(f'{who:4s} {action:6s} managed={managed!s:5s} -> {decide(s, file_, action, {"device_managed": managed})}')
Output
ana  read   managed=True  -> permit (P1)
ana  read   managed=False -> deny (P3)
ana  update managed=True  -> deny (default)
ana  update managed=False -> deny (P3)
raj  read   managed=True  -> deny (default)
raj  read   managed=False -> deny (P3)
raj  update managed=True  -> permit (P2)
raj  update managed=False -> deny (P3)

Notice the combining rule in the example: an explicit deny overrides any permit, and the absence of a permit means deny. Raj, a records officer, can update the file from a managed device even though his privacy training has lapsed, because the update policy does not check training; the read policy does, so he cannot read. Reviewing a policy set for such gaps is exactly what policy testing is for, and it is much easier when policies are code with tests than when they are scattered through application logic.

Combining RBAC and ABAC

Most organizations use roles for coarse, stable entitlements and attributes for fine-grained, contextual decisions. A role answers what kind of work this person does; attributes answer whether this particular request, on this particular record, in these circumstances, is appropriate. Identity governance tools manage role membership through joiner, mover and leaver processes and periodic certification, while policy engines evaluate attributes at run time. Groups in a directory are the usual vehicle for roles, and group membership is often passed to applications in SAML assertions or OIDC tokens, as lesson 6 described. Nesting groups inside groups simplifies administration but can obscure who really has access, so reviews must expand nested memberships.

Using roles, attributes and constraints together
NeedBetter handled byExample
Stable job functionRoles (groups)Accounts payable clerk can enter invoices
Relationship between user and dataAttributesClerk sees only invoices for their business unit
Time, location, device healthAttributes or risk-based rulesPayments approved only from managed devices during business hours
Temporary or exceptional accessTime-bound grantsAuditor gets read access for 10 days
Conflicting dutiesSeparation of duties constraintsNo one holds both vendor creation and payment approval

Separation of duties in practice

Separation of duties prevents fraud and error by ensuring no one person controls every step of a sensitive process. In practice it is implemented as a conflict matrix: pairs of entitlements that must not be held, or used, by the same person. Identity governance tools check new requests against the matrix before approval and scan existing access for violations. Where a small organization cannot separate duties fully, compensating controls such as supervisory review of transactions, mandatory vacations and job rotation reduce the risk. Dual control, where two people must act together, such as two officers each holding half a combination, is a stronger form used for the most critical actions.

Checking current access against a separation-of-duties conflict matrix, and blocking a request that would create a conflict.
conflicts = {
    frozenset({'vendor-create', 'payment-approve'}): 'can create a fake vendor and pay it',
    frozenset({'payment-enter', 'payment-approve'}): 'can enter and approve own payment',
    frozenset({'user-admin', 'audit-log-admin'}): 'can grant access and erase the evidence',
}
access = {
    'lena':  {'vendor-create', 'payment-enter'},
    'omar':  {'payment-enter', 'payment-approve', 'report-view'},
    'grace': {'vendor-create', 'payment-approve'},
    'it-ops': {'user-admin', 'audit-log-admin', 'backup-run'},
}
for person, ents in access.items():
    found = [why for pair, why in conflicts.items() if pair <= ents]
    status = 'OK' if not found else 'VIOLATION: ' + '; '.join(found)
    print(f'{person:7s} {status}')
request = ('lena', 'payment-approve')
would_have = access[request[0]] | {request[1]}
blocked = [why for pair, why in conflicts.items() if pair <= would_have]
print('Request', request, '->', 'blocked: ' + blocked[0] if blocked else 'allowed')
Output
lena    OK
omar    VIOLATION: can enter and approve own payment
grace   VIOLATION: can create a fake vendor and pay it
it-ops  VIOLATION: can grant access and erase the evidence
Request ('lena', 'payment-approve') -> blocked: can create a fake vendor and pay it

Cloud authorization policies

Cloud platforms implement authorization through policies attached to identities, groups, roles and resources. Although syntax differs between providers, the evaluation logic is similar: requests are denied by default; an explicit allow in an applicable policy grants access; an explicit deny anywhere overrides any allow; and organization-level guardrails, such as service control policies, set the maximum permissions any account can have. Resource-based policies, such as a storage bucket policy, can grant access to identities in other accounts, which is powerful and a frequent source of accidental public exposure. Permission boundaries limit what a delegated administrator can grant. Because cloud policies are easy to write broadly, with wildcards such as an action of star on a resource of star, organizations use policy analyzers that flag public or cross-account access and unused permissions so that roles can be trimmed toward least privilege.

Worked problem

Explicit deny wins

A developer's role has a policy allowing all storage actions in the development account. An organization-level guardrail denies deleting any bucket tagged as holding logs. The developer tries to delete a log bucket. What happens, and why is this design useful?

Show solution
  1. The role's allow covers the delete action.
  2. The guardrail's explicit deny also matches the request.
  3. An explicit deny overrides any allow, so the request is denied.
  4. The guardrail protects audit evidence regardless of how broad any individual role becomes, and cannot be removed by account administrators.

Answer: Denied. Central explicit denies are a robust way to enforce non-negotiable rules, such as protecting logs or blocking unapproved regions, across every account.

Privileged access management

Privileged accounts can change systems, read any data, create other accounts and disable security controls. They include domain and cloud administrators, database administrators, root accounts, network device administrators, service accounts with broad rights and break-glass accounts. Privileged access management, PAM, is the set of processes and tools that control them, and it is one of the most effective investments an organization can make, because attackers who obtain administrator credentials can do almost anything.

Privileged access management controls
PAM controlWhat it doesRisk addressed
Inventory and ownershipDiscovers every privileged account and assigns an ownerUnknown or orphaned admin accounts
Credential vaulting and rotationStores admin passwords and keys; rotates after each use or on scheduleShared, static, known passwords
Just-in-time elevationGrants privilege for a limited time after approvalStanding privilege that attackers can use any time
Session brokering and recordingConnects admins without revealing credentials; records sessionsCredential theft; lack of accountability
Privileged access workstationsHardened devices used only for administrationMalware on daily-use devices capturing admin credentials
Command control and monitoringRestricts or alerts on dangerous commandsMisuse by insiders or attackers
Break-glass proceduresSealed emergency accounts with alerts and post-use reviewLockout when normal access fails

The goal is to reduce standing privilege toward zero. Instead of an administrator holding domain administrator rights permanently, they request elevation for a specific task, an approver or automated policy grants it for, say, two hours, the session is brokered and recorded, and the privilege expires automatically. Even if the administrator's everyday account is phished, the attacker gains nothing privileged. Combined with the tiered model from lesson 5, separate administrator accounts and phishing-resistant authentication, just-in-time access removes much of the value of credential theft.

Flow from left to right: an administrator on a privileged access workstation requests elevation for a change ticket; the PAM system checks the ticket and policy and an approver grants two hours; the PAM broker opens a recorded session to the target server using a vaulted credential the administrator never sees; at expiry the privilege is removed and the credential rotated. A timeline below contrasts standing privilege, a full bar across 24 hours, with just-in-time privilege, a short block of two hours.
Just-in-time privileged access: approval, brokered and recorded session, automatic expiry and rotation.
Quantifying how just-in-time elevation shrinks the window in which stolen administrator credentials are useful, and reviewing break-glass use.
# Hours per year during which a stolen admin credential would be usable
admins = 12
standing_hours = admins * 365 * 24
# Just-in-time: each admin elevates about 3 times a week for 2 hours
jit_hours = admins * 3 * 52 * 2
print(f'Standing privilege exposure: {standing_hours:,} admin-hours per year')
print(f'Just-in-time exposure:       {jit_hours:,} admin-hours per year')
print(f'Reduction: {1 - jit_hours / standing_hours:.1%}')
# Break-glass accounts should alert on every use; review a log
uses = [('2026-03-02 03:14', 'bg-domain-1', 'INC-4471'), ('2026-07-19 22:05', 'bg-cloud-1', None)]
for when, acct, ticket in uses:
    print(f'{when} {acct}: ' + ('linked to ' + ticket if ticket else 'NO INCIDENT TICKET - investigate and rotate'))
Output
Standing privilege exposure: 105,120 admin-hours per year
Just-in-time exposure:       3,744 admin-hours per year
Reduction: 96.4%
2026-03-02 03:14 bg-domain-1: linked to INC-4471
2026-07-19 22:05 bg-cloud-1: NO INCIDENT TICKET - investigate and rotate

Worked problem

Rolling out PAM

A regional insurer has 38 people in its Domain Admins group, shared root passwords on Linux servers recorded in a spreadsheet and no recording of administrator sessions. The CISO has budget for one year. Propose a phased plan.

Show solution
  1. Phase 1: discover and inventory all privileged accounts, cut Domain Admins to the few people who administer Tier 0, give everyone else delegated rights and separate administrator accounts.
  2. Phase 2: vault and rotate shared root and local administrator passwords, retire the spreadsheet and require check-out with an individual sign-in.
  3. Phase 3: introduce privileged access workstations and phishing-resistant authentication for administrators, and broker and record sessions to critical servers.
  4. Phase 4: move to just-in-time elevation linked to change tickets, alert on use outside it, seal and test break-glass accounts.

Answer: Start by reducing who is privileged and removing shared secrets, then add brokering, recording and just-in-time access. Each phase measurably reduces the chance that one stolen credential becomes a full compromise.

Thinking like a manager

Authorization questions often hinge on architecture and privileged access. Know the PEP, PDP, PIP and PAP roles; know that explicit deny overrides allow and default is deny; know that separation of duties is enforced with conflict matrices and compensated for with review where staff are few. Above all, treat privileged access as the highest risk: the best answers reduce the number of privileged accounts, remove shared credentials, separate administrator accounts and devices, and replace standing privilege with just-in-time, recorded access.

Common mistakes

  • MistakeEmbedding authorization rules separately in every application.

    InsteadCentralize policy where practical, with consistent enforcement points and tested policy-as-code.

  • MistakeLetting the policy decision point fail open when unavailable.

    InsteadFail closed for sensitive resources and design the decision point for high availability.

  • MistakeGiving administrators permanent membership in powerful groups.

    InsteadUse just-in-time elevation with approval, recording and automatic expiry.

  • MistakeKeeping shared administrator passwords in a spreadsheet.

    InsteadVault credentials, check them out with individual sign-in and rotate them after use.

  • MistakeWriting cloud policies with wildcard actions and resources.

    InsteadGrant specific actions on specific resources and use analyzers to remove unused permissions.

Summary and key terms

  • The PEP enforces, the PDP decides, PIPs supply attributes and the PAP manages policy.
  • Policy-as-code makes authorization rules versioned, reviewed and testable.
  • Roles handle stable functions; attributes handle context and relationships.
  • Separation of duties is enforced with conflict matrices and compensated with supervisory review where needed.
  • In cloud policies, default is deny, explicit allow grants and explicit deny always wins.
  • PAM inventories, vaults, brokers, records and time-limits privileged access.
  • Just-in-time elevation drastically reduces the value of stolen administrator credentials.
Policy enforcement point
The component that intercepts requests and enforces authorization decisions.
Policy decision point
The component that evaluates requests against policy.
Policy information point
A source of attributes used in authorization decisions.
Policy administration point
Where authorization policies are created and managed.
XACML
An OASIS standard language and architecture for attribute-based authorization.
Policy-as-code
Expressing authorization policies as version-controlled, testable code.
Privileged access management
Controls for administrator and other high-privilege accounts.
Just-in-time access
Granting privilege only when needed and only for a limited time.
Standing privilege
Privilege held permanently whether or not it is in use.
Dual control
Requiring two people to act together to complete a critical action.

Practice problems

Work each problem on paper first, then reveal the answer to check.

  1. Which component evaluates a request against policy?

    Show answer

    The policy decision point.

  2. In most cloud policy engines, which wins: an explicit allow or an explicit deny?

    Show answer

    The explicit deny.

  3. What should a PEP do if the PDP is unreachable for a sensitive resource?

    Show answer

    Fail closed and deny.

  4. What is the purpose of a separation-of-duties conflict matrix?

    Show answer

    To identify pairs of entitlements one person must not hold or use together.

  5. Name two compensating controls when duties cannot be separated.

    Show answer

    Supervisory review of transactions and mandatory vacations or job rotation.

  6. What is a privileged access workstation?

    Show answer

    A hardened device used only for administrative work.

  7. What does session brokering prevent?

    Show answer

    Administrators seeing or capturing the privileged credential.

  8. Why are nested groups a review risk?

    Show answer

    They can hide who actually has access unless expanded.

  9. What must happen after every use of a break-glass account?

    Show answer

    An alert, a review against an incident record and credential rotation.

  10. Give one advantage of policy-as-code.

    Show answer

    Policies can be version-controlled, reviewed and tested automatically.

Lesson quiz · 5 questions

Score 60% or more to complete this lesson.

Take the quiz