started: 2022-OCTOBER-21
Harlow, K
This RFC blueprints a Platform Access Control Model (ACM).
Goal:
- Centralized and Standardized Access Control Model
- Authentication and Authorization At Central Gateway
- Consolidated Approach to Access Assignment / Fully Embrace Policy-Based Model
Method:
- (I) Having a service→resource attribute map used to describe and evaluate access.
- (II) Consolidating how access is assigned to a single strategy: by policy.
- (III) Enforcing authentication and authorizations at a centralized gateway
The proposed access control model (ACM) is framed by the principles: (a) access is described via resource; and (b) access is granted via policy.
That is, (I) we **(service owners) **describe a universe of resources made available by our public APIs; (II) consumers (resource owners) define policies ****************for who can access what within the bounds of that universe; and (III) those policies prevent, determine, audit, and grant access in the Platform. The ACM infrastructure models three (decoupled) parts:
(I) Resource Attribution And Discoverability Model (RAD\M)
RAD\M infrastructure centralizes the collection of resources exposed in our platform (called the resource universe); and a mapping of service endpoints that act on those resources (called service statements).
- The resource universe is a publicly discoverable list of resources; a resource is an attribute-like name representing a service data type, or collection of types, referenced in authorization policies **(PBA) to assign access to APIs which have that resource attributed.
- The service statements **are an internal mapping of service endpoints→resource; a service statement attributes a resource to a particular service path (or wildcard) endpoint. The central enforcement point (CEP) evaluates policy access to a requested resource by comparing what the policy allows vs. what is required by the best matched service statement.
The RAD **model **relies on ingestion of a configuration file at the individual service-level of public APIs. These service-level files are compiled to form both the resource universe and service statements, then made discoverable via a centralized broker-like agent. The primary utility of RAD is to provide necessary context for (a) authorization to be centrally enforced; (b) access assignments to be determinable and auditable; (c) to have a determinable rule set for evaluating access; (d) anti-corruption layer.
- (I.1) Resource Attributions (s manipulates r) **are explicitly defined for every service’s public API.
- (I.2) Resource Attributions (s manipulates r) **are decoupled from any authorization-related designations.
- (I.3) Resource Attributions (s manipulates r) **are decoupled from service functional code.
- (I.4) Resource Attributions (s manipulates r) **are defined within a specification language format.
- (I.5) Resource Attributions (s manipulates r) **are validated pre-service deployment.
- (I.6) Resource Attributions (s manipulates r) **are discoverable from a centralized broker.
- (I.7) Resource Attributions (s manipulates r) **are auditable.
(II) Policy-Based Access Model (PBA\M)
The PBA\M **is the interface for access assignment. Its infrastructure defines the policy model, access assignment strategies, and method of assuming a policy’s authorization.
- The policy is an account-scoped object that defines access statements and principle requirements. The policy:statements are a collection of simple **************resource-based (via RAD) access grants.
- The policy:principles are the set of users who have been assigned permission to assume some policy. The policy:requirements dictate an optional set of just-in-time conditions a principle must meet to assume it e.g., ip:address.
The PBA model is similar to a subset of AWS IAM in that principles are given permission to assume an AuthorizationPolicy and **the Principle assuming that policy is allowed to execute all accesses defined by it and only it. It is evaluated at the centralized enforcement point (CEP). The model decouples authorization from authentication; and consolidates different access strategies for e.g., account vs user scopes, in the Platform.
- (II.1) Resource Policies (p is granted s:r) are persisted with a uniform policy schema in a single store.
- (II.2) Resource Policies (p is granted s:r) are simple, fine-grained, and bound to the resource universe.
- (II.3) Resource Policies (p is granted s:r) are defined within a specification language format.
- (II.4) Resource Policies (p is granted s:r) are decoupled from credential items (e.g., users, tokens).
- (II.5) Resource Policies (p is granted s:r) are dynamic and have immediate effect.
- (II.6) Resource Policies (p is granted s:r) are revokable.
- (II.7) Resource Policies (p is granted s:r) are auditable.
![Uploading ac
(III) Centralized Enforcement Point Model (CEP\M)
The CEP\M **is the ACM infrastructure concerned with evaluating access at a central point i.e., a gateway. It models the authentication of a request’s credential token, and the authorization of its policy - removing that responsibility from individual service APIs.
- The credential token is an opaque token that is used to store the userId and account membership. It’s secret is the first part of a request’s authorization-header used to identify the user e.g.,
"token 1ae2f755xuw-q2-1px/Auditor"
The CEP **model **is the matrix point; granting or denying a request by (a) validating the request’s credential token; (b) validating the credential has principle rights to assume the policy; (c) validating the credential meets the policy’s **principle requirements; and (d) comparing the policy’s granted resources to the resource required by the request’s best-matched service statement. In this model the policy’s data filters, if present, are passed down to the service.
- (III.1) Resource Authorizations (is p allowed s:r) **are decoupled from service API layer.
- (III.1) Resource Authorizations (is p allowed s:r) **are evaluated independent of any context information about what service or resource attribute it’s being evaluated for.
- (III.2) Resource Authorizations (is p allowed s:r) are decoupled from the principle/credential context.
- (III.3) Resource Authorizations (is p allowed s:r) **are applied at a central gateway point.
- (III.4) Resource Authorizations (is p allowed s:r) are evaluated in a pure functional and standardized way.
- (III.5) Resource Authorization (is p allowed s:r) are adherent to the Failsafe Default principle.
![Uploading acm-
This is a sudo sample of the ACM to illustrate the three models’ (RAD\M, PBA\M, CEP\M) role, responsibilities, and interaction points that link them.
(1) Assume that our mock Platform has compiled the following centralized resources and service statements from all our services (RAD\M)
//resource universe
"compliance:controlsMapping"
"compliance:evidence"
"compliance:evidence:external"
"compliance:framework"
"compliance:libraryItem"
"compliance:requirement"
"compliance:standard"
"dashboard"
"iam:account"
"iam:api-key"
"iam:client"
"iam:group"
"iam:group:membership"
"iam:invitation"
"iam:token"
"iam:user"
"iam:user:account"
"iam:user:identity"
"integration:instance"
"integration:sync-job"
"parameter"
"query:edge"
"query:entity"
"query:rawData"
"query:rawData:version"
"query:relationship"
"query:vertex"
"question"
"rule:instance"
"rule:invocation"
"settings:accountSettings"
//service statements
"compliance:compliance/evidence/*":"compliance:evidence"
"compliance:mutation/createControlMapping":"compliance:controlsMapping"
"compliance:mutation/uploadExternalEvidence":"compliance:externalEvidence"
"compliance:query/framework":"compliance:framework"
"compliance:query/noteEvidence":"compliance:evidence"
"compliance:query/requirementNote":"compliance:requirement"
"compliance:query/requirementNoteUserEvidence":"compliance:requirement"
"compliance:query/userEvidenceWithUpload":"compliance:evidence"
"dashboard:dashboard/*":"dashboard"
"dashboard:query/getDashboard":"dashboard"
"iam:account/group/membership/*":"iam:group:membership"
"iam:account/groups/*":"iam:group"
"iam:account/users/*":"iam:user"
"iam:mutation/createToken":"iam:token"
"iam:mutation/inviteUser":"iam:invitation"
"iam:query/getUser":"iam:user"
"iam:query/getUserAccounts":"iam:user:account"
"iam:query/getUserProvider":"iam:user:identity"
"iam:query/invitations":"iam:invitation"
"iam:query/resolveToken":"iam:token"
"integration:integrations/sync/*":"integration:sync"
"integration:mutation/createIntegration":"integration:instance"
"integration:mutation/updateIntegration":"integration:instance"
"integration:query/myIntegrations":"integration:instance"
"parameter:paramters/*":"parameter"
"query:graph/vertexNeighbors":"query:vertex"
"query:mutation/createEntity":"query:entity"
"query:mutation/createRelationship":"query:relationship"
"query:mutation/deleteEntity":"query:entity"
"query:mutation/updateEntity":"query:entity"
"query:mutation/updateRelationship":"query:relationship"
"query:mutation/upsertEntityRawData":"query:rawData"
"query:query/edge":"query:edge"
"query:query/entityCount": "query:entity"
"query:query/entityRawData":"query:rawData"
"query:query/entityRawDataVersions":"query:rawData:version"
"query:query/relationship":"query:relationship"
"query:query/typeCount":"query:entity"
"rule:mutation/createRule":"rule:instance"
"rule:query/myRules":"rule:instance"
"rule:rules/createRule":"rule:instance"
"rule:rules/evaluate":"rule:invocation"
"settings:settings/*":"settings:accountSettings"
(2) Assume some customer account, xDev, defines an Authorization Policy: AWS-Auditor (PBA\M).
- xDev chose to assign someone with userId:
000-000-000
the right to assume this policy. - xDev wants to limit this user’s right to assume the policy only when their location is identified by the ip:address:
10:00.01
- xDev wants this policy to have only auditor-related access to resources and to filter the data to specific AWS stuff in some cases. It also needs full token access.
{
accountId: 'xDev',
authorizationPolicyId: '934-x23-543',
authorizationPolicyNameId: `AWS-Auditor`,
authorizationPolicyPrincipleRequirements: {
ip_address: [10.00.01],
},
authorizationPolicyStatements: [
"read":"query:*":[{"_tag":"aws"}],
"read":"compliance:evidence":["*"],
"read":"compliance:standard:*":[{"type":"aws"}],
"read":"integration:instance:*":[{"id": ["aws_19300-22-876", "aws_19300-11-644"]}],
"admin":"integration:sync:*":["*"],
"admin":"question:*":["*"],
"admin":"iam:token":["*"]
]
}
{
accountId: 'xDev';
principleId: 'user:0000-0000-0000';
credentialTokenId: '1ae2f755xuw-q2-1px';
credentialTokenScope: 'session' | 'api'
credentialTokenRevoked: false;
__issued: 1666291438;
__expires: 1766291438;
}
{
userId: '0000-0000-0000',
accountId: 'xDev',
authorizationPolicyId: 'AWS-Auditor'
}
(3) the user: 000-000-000 (assuming membership in the xDev account) can login to the xDev account to get issued a valid session credentialToken
that is stored as a browser cookie. On future requests, this credentialToken is attached.
───WEB────────┬─────────────┐
(1) apps.xxx.io│ USER │
──────────────────┼─────────┴──────────┐
│AUTHENTICATED: FALSE│
└────────────────────┴─────/LOGIN
└──http://iam/authenticate/account/xdev
(+) Has valid account membership
(+) Has valid account login provider
(+) Has valid account policies assigned
[RETURN]:
┌── credential_token: {
│ accountId: 'xDev';
│ principleId: 'user:0000-0000-0000';
│ credentialTokenId: '1ae2f755xuw-q2-1px
│ credentialTokenScope: 'session';
│ credentialTokenRevoked: false;
│ __issued: 1666291438;
│ __expires: 1766291438;
│ },
│ authorized_policies: [
│ `AWS-Auditor',
│ 'User'
│ ]
│
└───────WEB────────┬────────┐
apps.xxx.io│ USER │
──────┬───────────┴────────┴───STORE-COOKIE┼
│ CREDENTIAL:'1ae2f755xuw-q2-1px' │
│ ASSUMED-POLICY:AWS-Auditor │
├────────────────────┬─────────────┘
│AUTHENTICATED: TRUE │
└────────────────────┘
(4) The user makes a request (CEP\M)
┌──────────────┴────────────────────┴───────────────────┐
│REQUEST:GET/compliance/evidence?type=aws HTTP/1.1 │
(2) │Authorization: "token 1ae2f755xuw-q2-1px/AWS-Auditor" │
└───────┬───────────────────────────────────────────────┘
│
(SEND│REQUEST)
│
│
│
▼
GATEWAY / CENTRALIZED-ENFORCEMENT-MODEL (CEM)
┌────────────────────────────────────────────────────────┐ http://iam/resolve/1ae2f755xuw-q2-1px
│ ├──(1)─────► => { user: '000-000-000', account: 'xDev'}
│ (1) Validate AUTHORIZATION token credential │
│ (2) Fetch AUTHORIZATION token policy └───(2)─────► http://iam/000-000-000/assume/AWS-Auditor
│ => authorizationPolicyNameId: `AWS-Auditor`,
│ authorizationPolicyPrincipleRequirements: {
│ ip_address: [10.00.01],
│ },
│ authorizationPolicyStatements: [
│ "read":"query:*":[{"_tag":"aws"}],
│ "read":"compliance:evidence":["*"],
│ "read":"compliance:standard:*":[{"type":"aws"}],
│ "read":"integration:instance:*":[{"id": ["aws_19300-22-876", "aws_19300-11-644"]}],
│ "admin":"integration:sync:*":["*"]
│ "admin":"question:*":["*"],
│ "admin":"iam:token":["*"]
│ ]
│ }
│ (3) Inspect the REQUEST and GRANT/DENY
│ (a) Is PrincipleRequirements GRANTED/DENIED
│ (b) Is the requested resource attribution statement GRANTED/DENIED
│ - relevant statement: "compliance:compliance/evidence/*":"compliance:evidence"
│ - says that the attribute "compliance:evidence" is required.
│ - the AWS-Auditor policy includes "read":"compliance:evidence":["*"], so GRANTED.
│
(4) user: '000-000-000'
│ account: 'xDev'
│ filters: ["*"]
└─
│
│
│
│
▼
┌──┬─────────────────────┬─┐
│ │ FULLFIL REQUEST │ │
└──┴─────────────────────┴─┘
The following is part (3)
of the previous block, expanded. CEP determines if the policy grants access to the requested resource
GET https://xxxxx.io/compliance/evidence/aws_Xsfha-afg
|
transalte (format "service":"path")
|
= "compliance:compliance/evidence"
|
▼
lookup (*best match* attribution statement)
|
= "compliance:compliance/evidence/*":"compliance:evidence"
|
▼
check (does the policy grant (a) statement's requirement resource; (b) the action)
|
= (policy has: "read":"compliance:evidence":[{"id":"aws_Xsfha-afg"}])
= (requested-action: GET === "read")
= (statement-required-resource: "compliance:evidence")
|
? GRANT or DENY
|
▼
grant ("read:compliance:evidence")
RAD\M defines (a) the standard for service-by-service cataloging of public resources and endpoint→resource relationships; (b) the means to compile those catalogs and make them centrally discoverable.
A resource ****************represents some data type or action (or collection thereof), that is acted on by a service’s public API.
- It’s a public-facing attribute (think,
s3_bucket
,ecs_task
). - It can be hierarchical, e.g.,
LibraryItem
,LibraryItem:Evidence
. (note) on the flip side, policies also use hierarchical statements e.g.,[read:LibraryItem:*
orread:LibraryItem:Evidence:*
orread:LibraryItem:Evidence:Note:*
].
(a) The proposed standard is a configuration file at the root of every service with a public API; it contains two pieces of information:
- service resources**:** a ****listing of resources exposed by the service’s public API. format:
"service:resource"
- service statements************************:************************ a path-by-path (or query-by-query / mutation-by-mutation) mapping of resources exposed by the service’s public API. format:
"service:path":"resource"
// compliance-service "service resources"
"compliance:controlsMapping",
"compliance:externalEvidence",
"compliance:framework",
"compliance:libraryItem",
"compliance:evidence",
"compliance:requirement",
"compliance:standard",
//compliance-service "service statements" (Public API)
"compliance:mutation/createControlMapping":"compliance:controlsMapping"
"compliance:mutation/uploadExternalEvidence":"compliance:externalEvidence"
"compliance:query/framework":"compliance:framework"
"compliance:query/noteEvidence":"compliance:evidence"
"compliance:query/userEvidenceWithUpload":"compliance:evidence"
"compliance:query/requirementNote":"compliance:requirement"
"compliance:query/requirementNoteUserEvidence":"compliance:requirement"
...
// query-service "service resources"
"query:entity"
"query:relationship"
"query:vertex"
"query:edge"
"query:rawData"
"query:rawData:version"
// query-service "service-statements" (Public API)
"query:mutation/createRelationship":"query:relationship"
"query:mutation/updateRelationship":"query:relationship"
"query:query/relationship":"query:relationship"
"query:query/edge":"query:edge"
"query:query/entityRawData":"query:rawData"
"query:query/entityRawDataVersions":"query:rawData:version"
"query:mutation/upsertEntityRawData":"query:rawData"
"query:mutation/createEntity":"query:entity"
"query:mutation/updateEntity":"query:entity"
"query:mutation/deleteEntity":"query:entity"
"query:query/entityCount": "query:entity"
"query:query/typeCount":"query:entity"
"query:graph/vertexNeighbors":"query:vertex" //REST
...
(b) The centralization part of this model refers to the process in which a copy of each service’s catalog is persisted in a central location and used for discovery by several different processes e.g., enforcing authorization at the gateway; validating policies. [OCT.25] The mechanism for a “central broker” hasn’t been determined yet but I imagine it would look something like:
- Each service uploads its configuration file to s3 in a pre-deployment hook.
- The services configuration files in s3 are either fetched and composed on each cache miss request by the centralization broker or they are stored compiled in S3 and polls for updates on some interval or trigger.