Skip to content

Authorization vs Permission

  • by

Authorization and permission are not interchangeable terms. Confusing them invites security gaps, audit failures, and user frustration.

Authorization answers “what can you do?” while permission answers “who says you can do it?” One is a policy engine; the other is a policy record. Misalign the two and even the best cryptography cannot save your system.

🤖 This article was created with the assistance of AI and is intended for informational purposes only. While efforts are made to ensure accuracy, some details may be simplified or contain minor errors. Always verify key information from reliable sources.

Core Semantic Difference

Authorization is the runtime decision process. It evaluates claims, context, and policy to render an allow-or-deny verdict.

Permission is a static artifact stored somewhere—database row, LDAP attribute, JWT claim—that the decision process consumes. Without the process, the artifact is inert.

Think of permission as a ingredient and authorization as the chef who decides whether that ingredient belongs in today’s special.

Real-World Analogy: Airport Security

Your boarding pass is a permission: it lists gate and seat. The TSA agent’s scanner is the authorization engine; it checks the pass against no-fly lists, expiry rules, and your ID in real time.

Even if you hold a first-class pass, the scanner can still refuse you entry. The pass never guaranteed passage; it only supplied evidence.

Mechanics of Authorization Systems

Modern engines use attribute-based access control (ABAC) or policy-as-code languages like Rego. They ingest JSON tokens, query micro-services, and cache decisions for milliseconds to stay in the request hot path.

These engines never trust the permission payload alone. They re-verify signatures, check revocation lists, and evaluate context such as IP reputation or device health.

Performance Pattern: Decision Caching

Stripe routes 2,000 authz checks per second for dashboard actions. They cache negative decisions for five seconds to protect against thundering-herb retries while still honoring instant revocation via cache-busting webhooks.

Permission Storage Patterns

Store permissions close to identity data but never inside session cookies. Cookies grow, fracture across domains, and leak through XSS.

Instead, issue a short-lived OAuth access token whose scopes are frozen at creation time. Keep the full grant in a secure token introspection endpoint.

This split lets you revoke the grant without chasing distributed cookie jars.

Nested Roles vs Flat Scopes

GitHub migrated from nested team-based roles to flat, additive scopes in 2021. The flattening cut average evaluation time from 17 ms to 4 ms by eliminating recursive team lookups.

OAuth 2.0 Scope Misconceptions

Developers often treat scopes as permissions. Scopes are constraints on the token, not the user. A token bearing `read:mail` can still be rejected if the authorization policy demands MFA or a compliant device.

Always run a second policy layer inside your API that re-checks user attributes beyond the token.

Case Study: Strava API Breach

In 2020, Strava accepted tokens with the `public` scope for private segment leaderboards. Attackers replayed tokens from public clients to fetch sensitive athlete data. The fix added an authorization rule that matched token scope against segment privacy, not just user privacy.

RBAC vs PBAC vs ABAC

RBAC assigns roles to users; permissions hang off roles. It’s simple but explodes into role sprawl when you need fine-grained constraints like “accountant in EU can approve invoices under €10k only on weekdays.”

PBAC binds permissions directly to identities, skipping roles. It suits flat organizations yet suffers from orphan entries when employees switch teams.

ABAC evaluates any attribute—user, resource, environment. It expresses the same rule in one line: `user.department == “Finance” AND user.region == “EU” AND invoice.amount < 10000 AND dayOfWeek < 6`.

Migration Blueprint

Slack migrated 200 internal services from RBAC to ABAC over 18 months. They kept legacy roles as synthetic attributes to avoid big-bang cutover. Authorization latency rose only 0.3 ms because decisions were pre-compiled into Envoy filters.

Policy-as-Code Tooling

Write policies in version-controlled Rego, Cedar, or Kotlin. Store them in the same repo as micro-service code so pull-requests trigger policy unit tests.

Embed a decision simulator in CI that replays last week’s audit logs against the new policy. Fail the build if any previously allowed request is now denied, preventing silent regressions.

Testing Tactic: Shadow Mode

Netflix runs new authorization policies in shadow mode for 48 hours. Real traffic is evaluated but not enforced; discrepancies are logged and alerted. This caught 23 over-deny bugs in 2022 without impacting a single user stream.

JWT Claim Design

Keep claims small; every kilobyte inflates latency on mobile. Encode only high-cardinality data like `user_id` and `team_id`. Derive low-cardinality flags like `is_admin` at runtime from a policy data service.

Sign with ES256 to cut token size by 30% compared to RSA256. Rotate signing keys every 24 hours without user impact by publishing JWKS endpoints that clients cache for five minutes.

Revocation Strategy

Revoke by hash, not by ID. Store a SHA-256 digest of the `jti` claim in Redis with a TTL equal to token expiry. Validation micro-services check the digest in 0.2 ms without parsing the full token.

Micro-Service Sidecar Pattern

Inject an Envoy sidecar that intercepts every ingress call. The sidecar calls OPA with a gRPC query containing the request path, method, and headers. Your application code stays agnostic; a single Kubernetes annotation enables authorization.

This enforces consistent policy across polyglot services written in Go, Python, and Rust without importing SDKs.

Performance Benchmark

A 2023 CNCF study showed sidecar-based authz added 1.8 ms p99 latency versus 9.4 ms for in-process SDKs, because the sidecar reused open connections and cached decisions in shared memory.

User-Managed Permissions

Letting users grant access to their own data is powerful but dangerous. Google Drive’s “Anyone with the link” option created billions of publicly indexed files.

Instead, require the user to explicitly select a recipient identity from a type-ahead search. Generate a short-lived, unguessable URI that expires after first use or 24 hours, whichever comes first.

Log every grant event to an immutable ledger like AWS QLDB so auditors can reconstruct the chain of custody.

Consent UX Dark Pattern

Instagram experimented with one-click “allow all” buttons that pre-selected every scope. Authorization acceptance jumped to 96%, but downstream abuse reports tripled. They reverted to granular toggles and added a 5-second delay timer, cutting abuse by 41%.

GDPR and Data Processing Authorization

Under GDPR, permission (consent) must be freely given, specific, informed, and unambiguous. Authorization systems must then enforce purpose limitation; a token scoped for “analytics” cannot lawfully trigger ad targeting.

Implement dynamic scope downgrading: if the user later withdraws consent for marketing, silently strip that scope from active tokens on next introspection without forcing re-login.

Audit Trail Requirement

Supervisory authorities can demand a chronological log of every authorization decision. Store decision requests and responses as compressed Protobuf in object storage with WORM locks for ten years. Index by `user_id` and `data_category` to answer data-access reports within 72 hours.

Zero-Trust Network Implications

Zero-trust abolishes network perimeter trust but still needs fine-grained authorization. mTLS proves the service identity; authorization proves the service may invoke a specific RPC method.

Combine SPIFFE IDs with ABAC policies: `spiffe://billing/payments` can call `spiffe://ledger/post` only if the invoice amount is under the caller’s daily limit.

Policy Distribution at Scale

Uber compiles Rego policies into WebAssembly modules and ships them to 4,000 edge nodes via a CDN. Each module is signed; nodes refuse to load if the signature chain is broken. Updates propagate globally in 38 seconds without restarting proxies.

Edge Functions and Serverless

Serverless platforms bill per millisecond, so fat authorization logic hurts wallets. Pre-compute a minimal allow-list for each function version at deploy time and bake it into the function’s environment variables.

When a request arrives, a 3-line Node snippet checks the caller’s UID against the list and exits early if absent. The cold start penalty stays under 2 ms.

Vendor Lock-In Mitigation

Cloudflare Workers embeds an OPA-WASM shim. By storing policies in Rego, you can port the same logic to AWS Lambda or OpenFaaS without rewriting. Only the runtime glue changes.

Multi-Cloud Identity Federation

Federating Azure AD with AWS IAM introduces double authorization: Azure issues a SAML assertion, AWS IAM trusts it, but your application must still enforce resource-level rules. Bridge the gap by projecting Azure groups into AWS tags and writing IAM policies that reference those tags.

This avoids duplicating role definitions across clouds while keeping a single source of truth in Azure.

Latency Trap

Cross-cloud group lookups can add 300 ms if the SAML IdP is geographically distant. Deploy regional SAML proxies that cache assertions for 60 seconds and sign new ones locally. Dropbox cut login time from 480 ms to 95 ms for APAC users.

Future-Proofing with Verifiable Credentials

W3C Verifiable Credentials let users present cryptographically signed claims offline. A hotel can verify your age without calling the issuer, but the hotel’s authorization engine still decides whether 18+ is sufficient for alcohol service in that jurisdiction.

Design policy to accept VC proofs as one input among many; never replace runtime context evaluation.

Selective Disclosure Trick

Implement BBS+ signatures so users can prove “over 21” without revealing birthdate. The authorization policy simply checks the derived proof, reducing privacy surface while retaining compliance.

Leave a Reply

Your email address will not be published. Required fields are marked *