Skip to main content

How IAM works

Learn about Piiano Vault's identity and access management (IAM)

Identity and access management is how Vault governs access to APIs and data. This feature has two components:

Users and roles

A user represents the identity of a caller that requires access to an API operation or data in Vault. Each user has one role, and gains its access to Vault using a bearer token that can be an API key, JWT token from an identity provider (idp) such as Auth0, or more authentication strategies (Coming soon 🎁). Each role is a collection of access control capabilities and data access policies.

Vault has a built-in Admin user, with a special role called Admin. This role has the special "CapSystem" capability, which provides access to all API operations. By default, the Admin user cannot access data in production. However, you can control whether the Admin user can access data using the PVAULT_SERVICE_ADMIN_MAY_READ_DATA environment variable.


If you're using the hosted version of Vault, contact us if you wish to provide the Admin user with the ability to read data.

Access control

Access control governs access to API operations. API operations are classified into scopes. For example, the collections scope represents all the REST API operations with the /api/pvlt/1.0/ctl/collections prefix in their path. Capabilities then define access to methods within the scope. For example, the "CapCollectionsReader" capability provides access to all the GET operations in the "collections" scope. Each role can have one or more of these capabilities.

Capability evaluation and data access

When a user makes a REST API call or uses a CLI command, Vault determines whether the user's role includes the capability to perform the requested action. For a REST API call, for example, if the user doesn't have the required capability, the call is denied and a 403 error is returned.

Policy management

Policy management determines whether a user is allowed to complete an operation based on the data that the operation manipulates and how the data is manipulated. To do this, policy management uses the collection of policies associated with the user's role. A policy is a rule that contributes to the decision about whether a user can execute the requested operation.

This information defines each policy:

  • Type, either allow or deny.
  • Operations, a list of actions on data, including:
    • "read"
    • "write"
    • "delete"
    • "search"
    • "tokenize"
    • "detokenize"
  • Resources, a list of resource identifiers that describe data. See Resource identifiers for more information.
  • Reasons, a list of reasons for accessing data.

Operations, Resources, and Reasons must contain at least one value. The value of "*" denotes all possible values.

See IAM configuration file reference for more details on defining policies.

Policy evaluation and data access

When a user performs an operation in Vault, through the CLI or an API, the policy engine evaluates the operation against each policy in the user's role. Each policy then votes on whether to allow the user access. The policy's vote can be for, against, or an abstention. The policy engine allows the operation only when there is at least one allow vote and no deny votes.

To see how this works, assume that a user attempts to update all the properties of an object in a collection called employees using the Update object REST API operation. Also, assume that the employees collection has four properties, first_name, last_name, phone_number, and ssn.

If a user has a role that includes only this policy:

policy_type = "allow"
operations = ["write"]
reasons = ["*"]
resources = ["*"]

When the user attempts to update all the details for an object, the policy votes to allow access. This is because the policy permits the user to write data for any property and any reason. With no votes denying access, the policy engine allows the user to perform the operation.

If the role were to include this second policy:

policy_type = "deny"
operations = ["tokenize"]
reasons = ["*"]
resources = ["*/phone_number"]

Now, when the user attempts to update all of an object's details, two policies vote. This policy abstains from voting because the requested operation isn't trying to tokenize a property. With one vote for and one abstention, the policy engine allows the user to perform the update.

However, if the role includes this third policy:

policy_type = "deny"
operations = ["write"]
reasons = ["*"]
resources = ["employees/ssn"]

When the user attempts to update all of an object's details, this policy votes against allowing access. This is because the policy denies the user the ability to update the ssn property of the employees collection. Consequently, although there is still one vote for (and one abstention), the vote against allowing access means that the policy engine denies the request to update the object's details. For the REST API, this results in the call not executing, and a 403 error is returned.