Identity and access management

Identity and Access Management (IAM) is a system that defines how users access a platform's resources. StackPath's IAM system defines a user's access to their account or to the stacks on their account. Operations in StackPath's Control Portal and API are validated against the IAM system before they're executed.

Concepts

Users

A user is anyone that can login to the StackPath Control Portal or use the StackPath API. The IAM system manages policies assigned to resources, which in turn control that user's access to the platform. A relationship between a user and what they can do in the platform is called a binding.

Every StackPath account has a default "root" user that has full access to everything on the account and the account's stacks. That access cannot be taken away. If you ever need to change the "root" user on the account, please reach out to our support team.

🚧

Users have an ID but are identified by their email address in the IAM system.

Resources

A resource is any service or feature that StackPath provides. Resources can exist account-wide like billing and user management or they can be Stack-based like sites, compute workloads, and DNS zones.

Policies

A policy associates roles to users. Policies exist for an account or a Stack on an account. Accounts and Stacks have one policy, but that policy can have multiple bindings to allow fine-grained user and role control.

Stacks don't have policies when they're created, but we encourage you to create Stack-based policies to meet your organization's needs.

Roles

A role is a collection of permissions that is applied to a StackPath account or Stack. Users are assigned roles instead of individual permissions as policy bindings.

StackPath's IAM system has two pre-defined global roles:

  • roles/systemOwner: The user has full access their account and all of the account's Stacks. An account's root user has this role by default, and this role cannot be removed.
  • roles/systemAdmin: The user has access to everything on their account and Stack except billing user related services. This role is useful for resellers who want to assign Stacks to their clients while hiding billing information. We suggest applying this role to non-root users.

Every service in the StackPath platform has pre-defined viewer and admin roles to assign read and read/write permissions to those services. These roles are named according to their associated service:

To managePre-defined roles
Accounts and usersroles/identityViewer
roles/identityAdmin
Stacksroles/stackViewer
roles/stackAdmin
Account and Stack IAM policiesroles/policyViewer
roles/policyAdmin
Sites
Content delivery network
Web application firewall
roles/deliveryViewer
roles/deliveryAdmin
DNSroles/dnsViewer
roles/dnsAdmin
Edge computeroles/workloadViewer
roles/workloadAdmin
Edge compute networkingroles/ipamViewer
roles/ipamAdmin
SSLroles/sslViewer
roles/sslAdmin
Monitoringroles/monitoringViewer
roles/monitoringAdmin
Object storageroles/storageViewer
roles/storageAdmin

Viewing Stack and Account Policies

Place an HTTP GET request to the Get all account policies or Get a stack's IAM policy endpoints to see the account or Stack's IAM policy:

$ curl --request GET \
  --url https://gateway.stackpath.com/stack/v1/stacks/STACK_ID/iam/policy \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: bearer BEARER_TOKEN'

If the Stack has an IAM policy then the call returns a response with the Stack's policy bindings:

HTTP/1.1 200 OK
Date: Wed, 12 Aug 2020 00:05:54 GMT
Content-Type: application/json
Content-Length: 215
Connection: keep-alive
Strict-Transport-Security: max-age=15724800; includeSubDomains
Grpc-Metadata-Content-Type: application/grpc

{
  "stackId": "74dd3b65-5f01-4b1e-8fcc-ad8443568af7",
  "policy": {
    "bindings": [
      {
        "role": "roles/dnsViewer",
        "members": [
          "user:[email protected]",
          "user:[email protected]"
        ]
      }
    ],
    "version": 0,
    "createdAt": "2020-08-12T00:05:54.604071Z"
  }
}

An IAM policy has the following properties:

  • accountId or stackId: The account or Stack's unique ID
  • policy: The policy bound to the account or Stack. Every policy has the properties:
    • bindings: The bindings associated with the policy
      • role: The role applied in the policy binding
      • members: The users associated with the binding's role. Members are prefaced with "user:" and are identified by the user's email address
    • version: The policy's version. Version numbers start at 0 and are incremented every time the policy changes
    • createdAt: The date the policy was created

Account policies are applied to every API call. Stack policies don't override account policies, but they can make access to the Stack more permissible.

If a Stack doesn't have an IAM policy then querying for it produces a 404 Not Found error response:

HTTP/1.1 404 Not Found
Date: Tue, 11 Aug 2020 22:49:11 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
Strict-Transport-Security: max-age=15724800; includeSubDomains

{
  "code": 5,
  "message": "Policy not found",
  "details": [
    {
      "@type": "stackpath.rpc.RequestInfo",
      "requestId": "1bed05b22a509092",
      "servingData": ""
    }
  ]
}

Setting Policies

Send an HTTP PUT call to the Update account policies or Set a stack's IAM policy endpoints to update your account's or Stack's policy. The body of the request should contain the full policy to apply. This example adds the user [email protected] with the role roles/systemAdmin to the Stack policy described above. Remember to increment the policy's version in the request:

$ curl --request PUT \
  --url https://gateway.stackpath.com/stack/v1/stacks/STACK_ID/iam/policy \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: bearer BEARER_TOKEN' \
  --data '{
  "policy": {
    "bindings": [
      {
        "role": "roles/dnsViewer",
        "members": [
          "user:[email protected]",
          "user:[email protected]"
        ]
      },
      {
        "role": "roles/systemAdmin",
        "members": [
          "user:[email protected]"
        ]
      }
    ],
    "version": 1
  }
}'

When successful, the call returns new policy back to the caller:

HTTP/1.1 200 OK
Date: Wed, 12 Aug 2020 00:05:54 GMT
Content-Type: application/json
Content-Length: 215
Connection: keep-alive
Strict-Transport-Security: max-age=15724800; includeSubDomains
Grpc-Metadata-Content-Type: application/grpc

{
  "stackId": "74dd3b65-5f01-4b1e-8fcc-ad8443568af7",
  "policy": {
    "bindings": [
      {
        "role": "roles/dnsViewer",
        "members": [
          "user:[email protected]",
          "user:[email protected]""
        ]
      },
      {
        "role": "roles/systemAdmin",
        "members": [
          "user:[email protected]"",
        ]
      },
    ],
    "version": 2,
    "createdAt": "2020-08-12T00:05:54.604071Z"
  }
}

Removing a Stack's Policy

You cannot remove an account's policy, but you can remove a Stack's policy to have its access revert to your account's policy. Send an HTTP DELETE call to Delete a stack's IAM policy to remove the policy:

$ curl --request DELETE \
  --url https://gateway.stackpath.com/stack/v1/stacks/STACK_ID/iam/policy \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: bearer BEARER_TOKEN'

The call returns a 204 No Content response on success:

HTTP/1.1 204 No Content
Date: Fri, 14 Aug 2020 21:21:17 GMT
Connection: keep-alive
Strict-Transport-Security: max-age=15724800; includeSubDomains
Grpc-Metadata-Content-Type: application/grpc

Error Handling

API calls return a 403 Forbidden response If a user does not have permission to access the requested resource or perform the requested operation. See Error handling for more information on StackPath API errors.

HTTP/1.1 403 Forbidden
Date: Tue, 11 Aug 2020 22:15:02 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
Strict-Transport-Security: max-age=15724800; includeSubDomains

{
  "code": 7,
  "message": "Permission denied",
  "details": [
    {
      "@type": "stackpath.rpc.RequestInfo",
      "requestId": "dc33b2f909b1c79a",
      "servingData": ""
    }
  ]
}