Infrastructure
Security and Auth
Security policies control access to encrypted resources.
Ensuring the proper security of data is foundational to the Twisp infrastructure. Out of the box, data is securely encrypted both at rest and in transit and all access is authenticated via JWT tokens issued by the OpenID Connect 1.0 protocol.
Users can configure additional access settings by defining client policies within a CloudFormation template to set permissions on specific operations.
The authentication & authorization flow
The Twisp authentication process uses a policy-based approach to apply specific permissions to a principal granting or denying access to resources.
In a simplified form, the stages for the authentication process are:
- A principal issues an HTTPS request with their OIDC JWT and Twisp account IDs in the headers.
- The principal name is extracted from the JWT.
- Twisp finds the corresponding policies to apply using the principal name.
- The resulting policies are evaluated for authorization.
Making an authenticated request
All HTTPS requests to the GraphQL API must provide the following headers to allow for authorization:
Authorization: Bearer <JWT>
x-twisp-account-id: <AWS account id>
The JWT can be issued either with OpenID Connect or AWS IAM.
Authorizing a principal
Within a Twisp::Database::Client
configuration, the security principal is the authenticated name of the identity accessing the system. The client authorization system retrieves Policies based on the principal name.
For OIDC, this may be the issuing system URL. For AWS IAM, it may be the IAM role or user name.
// policies.yml
WebClient:
Type: Twisp::Database::Client
Properties:
Principal: !Ref WebClientARN
Policies:
- Effect: ALLOW
Actions:
- db:Select
Resources:
- public.*
Issuing tokens with OpenID Connect (OIDC)
Any JWT generated by an OpenID Connect 1.0 capable issuer is supported by Twisp for authentication. These tokens must be embedded in the Authorization
HTTP header.
When an API endpoint receives the JWT, it validates the token signatures against the issuer and—if valid—invokes the endpoint with a security principal set to the issuer iss
claim in the token.
All claims from the token are embedded in the context.auth.claims
transaction context variable. These claims are available for all security policies.
Issuing tokens with AWS Identity and Access Management (IAM)
Twisp can vend an OpenID Connect token in exchange for any authenticated IAM role or user. This allows a process running under an IAM role to retrieve a Twisp-issued OIDC token for access.
The issuer of these tokens is https://auth.${AWS::Region}.prod.twisp.com/token/iam
.
The security principal name that results from these tokens for policy lookup is equal to the original AWS IAM principal name, which is set in the sub
field of the token.
Read more about AWS IAM on their official docs.
Defining Policies for a Client
Within the configuration for a Twisp::Database::Client
, the Policies
property is used to define allow/deny rules for actions and resources.
The Policies
property contains a list of Policy
mappings. Each Policy
defines an Effect
(either ALLOW
or DENY
), a list of Actions
and Resources
to apply the effect on, and optional Assertions
to determine whether or not the policy should be applied.
When the system runs a transaction, it reviews all actions taken against resources to ensure every one is allowed based on the policies defined.
Logical combination of policies
Policies can be defined in any order because they are effectively applied as a chain of logical AND
statements scoped to the resource and action in question. When an authenticated principal attempts an action against a particular resource, they must have at least one ALLOW
policy applied to the resource/action pair. A single DENY
policy on the resource/action pair will block the operation.
Example Schema
The following schema shows a Twisp::Database::Client
resource definition with 3 policies applied to a web client principal.
These policies could be interpreted into plain language as:
- By default, grant the principal permission to perform CRUD actions on every public resource.
- Do not allow the principal to read the
ssn
property for thecustomers
resource. - Do not allow the principal to delete documents from the
customers
resource when theaddress
property is not null and theemail
property does not end with@twisp.com
.
// policies.yml
Transform: AWS::Serverless-2016-10-31
Parameters:
WebClientARN:
Default: arn:aws:iam::<AWS ACCOUNT ID>:role/site-twisp-com-SiteEdgeRequestRole-1KQFID9FYANM2
Type: String
Resources:
WebClient:
Type: Twisp::Database::Client
Properties:
Principal: !Ref WebClientARN
Policies:
- Effect: ALLOW
Actions:
- db:Insert
- db:Select
- db:Update
- db:Delete
Resources:
- public.*
- Effect: DENY
Actions:
- db:Select
Resources:
- public.customers.document.ssn
- Effect: DENY
Actions:
- db:Delete
Resources:
- public.customers.*
Assertions:
HasAddress: |
has(context.document.address)
HasTwispEmail: |
context.document.email.endsWith('@twisp.com')
Controlling access to Actions and Resources
Each Policy
allows for the specification of Actions
and Resources
to allow or deny access to.
In the above example, the second policy is defined such that the principal is denied access to the action db:Select
on the public.customers.document.ssn
resource.
Twisp defaults to DENY
for all actions and resources, so an explicit ALLOW
is required for any actions that should be permitted for a given principal.
Values for Resources
and Actions
on policies support the wildcards *
for a greedy match and ?
for single character matching.
List of all Actions
The set of values allowed in the Actions
list are:
db:Select
: read a documentdb:Insert
: create a documentdb:Update
: update the value(s) of a document's field(s)db:Delete
: delete a document
Format for the Resources ID string
The values for the Resources
property of a Policy
are resource ID strings. These strings follow the format:
<namespace>.<ledger>.<document|indexes|joins|references>.<propertyName>
Currently the only supported namespace
is public
, which contains all resources in the Twisp account.
Conditional application of Policies
The Assertions
property allows the conditional application of a policy.
Each key in the Assertions
contains a Common Expression Language (CEL) expression which is evaluated and combined with other assertions in a logical AND
chain. If any condition evaluates to false
, then the policy is not applied.
Within the expression, the context
object can be used to query properties of documents in the resources requested.
In the example schema above, the Assertions
defined on the third policy ensure that the policy will only be applied when both of the following are true
:
- The customer has an address (i.e. the
address
property is not null) - The customer's email ends with
@twisp.com
This effectively disables deleting records from the customers
resource when they have an address or a Twisp company email.
Encryption
Encryption in transit
Data is encrypted in transit via HTTPS connections for all external and internal API operations.
This protects against man-in-the-middle style attacks and prevents any malicious actors listening in on Twisp web traffic from being able to access the data.
Encryption at rest
All data stored in Twisp is encrypted at rest. Encryption keys are stored in AWS Key Management Service.
This protects against any breaches of the servers where Twisp data is stored. Even if a malicious actor gains access, they will not be able to view the data without the proper decryption keys.