Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Setting unique identifiers and human-readable names using OAA templates
By default the templates use the name
field for this purpose. However, names are not unique within some applications. In this case the templates offer an optional id
as a unique identifier, allowing name
to function as a non-unique display name.
Local User, Local Group and Local Role have an optional value id
that can be provided for each entity that serves as the unique identifier.
To use id
all Local Users, Local Groups and Local Roles must be defined with an ID. The name
and id
can be the same value as long it is unique for the entity type. For example a local role can have admin
for both the name
and id
.
The id
value becomes the key for referencing local users, groups and roles in the identity_to_permissions
section of the payload and for referencing group memberships.
Using id
s for mapping, instead of name
is recommended in most cases, especially if any of the following are true:
Entity names aren't unique in the application (if two users can have the name "Joe Doe" but each have a unique user id such as email
or login
or the applications unique id
).
The API references users, resources, and other entities by an ID instead of name. Using the same ID for the OAA payload will limit scenarios where you need to maintain a mapping of id
to name
in your connector.
For Custom Application to use
id
for Local Users, Groups and Roles all entities must use theid
field. To use theid
field for Resources all Resources and Sub-Resources must have anid
Resources and Sub-resource each can have an optional id
value. When provided, the resource name
does not need to be unique. To use id
, all resources and sub-resources must be defined with a unique ID. The id
value will be used to assign resource permissions in identity_to_permissions
.
Custom IdP also supports a optional unique identifier value identity
for Users and Groups. If not used, the entity name
must be unique and will be the primary identifier.
Veza requires each entity to have a unique identifier, used within the template to reference entities (which groups a user is a member of) and for Veza to use to track and display the entity. This is true for both the and templates
Strategies and best practices for OAA connector development
See the included topics for more information about developing an Open Authorization API connector.
Choosing your development environment and deploying an OAA connector
The Open Authorization API enables developers to push metadata to the Veza Authorization Graph using a standard JSON schema. To automate this process, you will need a way to periodically query the data source you want to integrate, populate the schema, and publish the populated template payload to your Veza instance using API calls.
You can interact with the Veza API from your client or language of choice. OAA connectors can (and have) been developed in a variety of languages. The only requirements are the ability to:
assemble a dict
or similar data structure and convert to JSON
make REST API calls to publish the payload
You can run OAAClient as a manual CLI tool for trial purposes, but should automate any long-running OAA implementation. A DevOps or SecOps team is typically responsible for establishing continuous integration of a Veza connector.
Customers are responsible for running their own connectors. The frequency your app must run will depend on use case, ranging from daily to hourly. Veza typically refreshes metadata for built-in integrations on an hourly basis. However, you can decide to publish OAA payloads on any schedule.
At a minimum, a deployed OAA connector should be able to:
Parse the data source and push an updated payload on a schedule
Securely handle secrets such as API keys
Teams should follow their preferred processes and use familiar or existing platforms. Some options include:
AWS Lambda function
Docker/k8s-based container
cron task
GitHub action
Veza expects the default push to contain a full payload. This will overwrite all information in the updated data source.
During development, it is usually most efficient to design your parser for a full discovery. It will be easiest to design the connector to assemble and push the full payload, and use the same code to publish updates.
To use incremental updates:
Set the is_incremental
flag in the payload to true
Add an add
, modify
or delete
operation to all entities
Naming, typing, and searching for top OAA entities
Before uploading entity metadata for an OAA integration, you must create a custom provider and at least one data source under that provider. The provider represents the type of application (such as "Jira Server") and determines the template used for all data sources (e.g."dev", "prod")created under that provider.
The OAA payload is pushed to a specific data source and updates the existing data.
A display icon can be set for the provider, shown throughout the Veza UI to identify the integration and its entities.
Naming the provider and data source is an important step in integration creation. In general,
The provider name should be unique to the integration. Avoid common terms such as "application". Separating providers for systems with several instances such as "production" and "development" can be a good idea.
The provider or data source value should be unique to the integration and incorporate an identifier such as hostname or other instance ID. This ensures that multiple instances of the integration can be separated if necessary.
Do not user random or date values in provider or data source names. Each run of the connector should result in the same provider and data source name, based on discovered values or a configuration parameter.
Each OAA Template supports a concept of name and type. The type enables search for all instances of a specific entity. For example, the Application Type identifies application entities such as users, groups, roles, and resources. It will enable search for all entities in an application. Setting the application type to Zendesk
will allow for search Zendesk Users
, Zendesk Groups
, and other entity types:
The app name
appears when searching for individual entities, and, to differentiate more than one instances of the same system. For example two instances of an application "Portal - Production" and "Portal - Development".
Strategies for extracting authorization, identity, and resource metadata
When planning an OAA connector, consider how you will gather the information you want to import into Veza. Refer to the application’s documentation to confirm you can obtain the required metadata from the host application.
Ideally, you will be able to list and collect metadata for:
User records
Group memberships
User roles and permissions
Resource names and metadata
For example, the Veza-GitHub connector utilizes the following endpoints (in addition to basic authentication and authorization APIs):
Web-based APIs are a common solution for SaaS apps, but not required for an OAA integration. Just because an endpoint exists does not mean that it returns useful information (some APIs are more designed for client automation than audits). Possible choices for sourcing metadata include:
From a database: Is data for a hosted app available in a database your connector can query?
File-based extraction: is the metadata available in source code or a configuration file, or an exportable report (such as CSV)?
Other options: does the provider have an SDK or CLI interface you can use to retrieve data?
If no machine-readable data is readily available, even screen scraping could be a solution. There are many creative options for extracting the information to populate the template, although an API will typically be the most usable option.
query the source application (or , or another method) to collect identity, resource, and authorization metadata
Veza provides a Python SDK . This package provides functions for generating and submitting the JSON payload. The Veza developed community connectors use this toolkit, along with all integrations built by active customer developers.
OAA does support as an optional behavior–if your custom data source or identity provider provides a way to get individual changes over time, you could design your connector to parse only new or changed entities, and push updates individually (perhaps in response to detected changes). However, this approach will be more complicated. A full parse-and-push will be more efficient, unless there's a method to query the provider for differences since the last push.
How to use the Application Template to represent various types of application
The OAA Application template allows for representing the basic elements of an application and is flexible to allow for multiple different patterns.
The custom application template provides a framework for describing:
Who: Users, Groups, and other identities
What: Application, resources, sub-resources
How: Permissions, canonical mappings, roles, authorization
Application
The Application itself is the first entity as part of the Application submission. The application has a name and a type. The name can be specific such as "West Production" and the type is typically the vendor, technology, or product such as "GitLab". Veza will group the rest of the entities by the application type such as "GitLab Users" across all instances of an application type, however, entities will only be directly associated with the application they are submitted with. Applications additionally can have custom properties assigned to further enrich the data. This can be especially useful to distinguish between multiple instances of an application type.
Local Users
The Local User object represents the local user of the application. It can store application-specific information such as the identifier, name, active status, last login time, and custom properties specific to the application. An external Identity can be associated with the user, enabling Veza to connect the source Identity Provider (IdP). This creates a connection in the Authorization Graph between the application user and a source identity such as Okta or Active Directory. Users can be added to groups, or have roles and permissions directly assigned.
Local Groups
Local Groups represent a collection of users. Groups can store additional metadata about the group to support search and filters. Groups can also contain other groups, to model applications that support nested groups. Groups can have role and permission assignments in the application.
Local Roles
Local Roles represent a collection of permissions within an application. When a user or group is assigned a role, that user or group is assigned all the permissions from the role. Like other entities, roles can contain additional properties to enrich the metadata of the role, such as description or application-specific attributes.
Permissions
OAA allows for expressing the permissions of the application in its own terms. In the Application Template, permissions are defined by application-specific terms such as "Close Ticket" or "Approve User". These permissions will also allow for setting corresponding Veza Canonical Permissions such as "Data Read", "Data Write", or "Metadata Read". This enables search and filters across permissions using CRUD-like equivalents.
Available Canonical Permissions: - DataRead - DataWrite - DataCreate - DataDelete - MetadataRead - MetadataWrite - MetadataCreate - MetadataDelete - NonData - Uncategorized
Resources
Resources can be used to model components within applications that users can be assigned roles or permissions on. For example, an OAA resource may be used to model a Project in an application like Jira. Users can have different roles in different projects, by assigning the correct users or groups their respective roles on the resources. Each resource has a Type which Veza uses when displaying and searching the resources for an application. Applications can have multiple types of Resources. Like other entities, resources can have properties containing additional resource metadata.
Below are some examples of how applications may be modeled in OAA. These examples have all been implemented using the Application template.
PagerDuty is an example of an application where users can have roles at the application level (global roles) but also within the PageDuty Teams that a user is a member of. Understanding which Users are part of which Teams and what level of access they have in those Teams is important for reviewing access in an application like PagerDuty. The OAA Application template can be used to model this type of application using the following mappings.
User
Local User
Team
Local Group
To group the Users
Application Role
Local Role
Applied to the Application
Team
Local Resource
To represent the User's role in the Team
Team Role
Local Role
Applied to the Team Resource
With this model, Veza can show the levels of access users have within the overall Application and their individual Teams. In this example, we can see the User Gary Ward has the Role "Restricted Access" in the PagerDuty Application, and the "Observer" Role in the "Support" Team Resource.
GitLab is a good example of a more complex application that can be modeled using the Veza OAA Application Template. By correctly modeling the applications, Veza can show which users have access to GitLab Groups and Projects to show details beyond just "who has access to GitLab?"
User
Local User
Group
Resource
Project
Sub Resource
Each GitLab User is represented with the Application Local User. GitLab assigns each user a unique ID number to each user, using this as the ID for the Local User makes it easier when associating groups and roles to Projects later. The Local User also allows for setting properties to represent the user's state such as is_active
or last_login_at
, custom properties to represent GitLab-specific properties can also be utilized like if the user is licensed or not. The identity for the Local User is set to enable OAA connection to source Identity Providers configured in Veza.
A GitLab Group represents both a collection of Users, a collection of Projects, and possibly other sub-groups. This is a good example of where some mapping needs to be done to represent GitLab using the Application Template. Since GitLab Users have a specific role in the GitLab Group, it is correct to represent the GitLab Group as an OAA Resource. Members are assigned an OAA Local Role to the Resource that represents the GitLab Group, denoting their level of access (Owner, Developer, Guest, and so on). Veza can return all the members of a GitLab Group by querying for the relation between the OAA User and the OAA Resource. Additionally, the role within the GitLab Group is preserved by the OAA Role.
GitLab Projects are also represented as an OAA Sub-Resource with the type set to Project. The Project Sub-Resource is added to the corresponding Group resource. Local User and Local Groups can be assigned roles on the project based on their direct assignments. In the case of GitLab, permissions can be inherited from above. This is an optional behavior for permissions, which can be set to automatically apply to sub-resources, or only apply directly to the assigned resources. Additionally, permissions can be set to apply to certain types of resources so that roles can be used across resources and only the correct permissions will be applied.
Tags are applied by providing a key and an optional value for each. A new tag will be created if a matching one doesn't already exist.
Due to superior integration with other Veza functionality and ease of updates, custom properties are recommended as the best approach for adding metadata to OAA entities, unless tagging is required as part of a larger campaign.
The operation
field indicates the change to make. Valid operation
s are:
"add"
, "modify"
, "delete"
to create, change, or remove an entity.
"add_tag"
, "delete_tag"
to update a tag without altering the entity.
Using local roles, local users, and canonical permissions to describe access
local_users
to describe local and federated identities and service accountsMost applications will have some concept of a “local user” that can have varying permissions to data and metadata. Most modern cloud applications offer some form of single sign-on. In some cases, local user accounts correspond to an external federated identity, or even only exist ephemerally.
The Open Authorization API is able to represent local users, local groups, and external identities. An external identity could be an user connecting directly to a resource through Single Sign On, or an SSO group. A local user could be a just-in-time account created when an IdP user first connects.
The OAA template supports direct permissions from IdP users to resources. However, including a local user entity in your OAA mapping strategy is still recommended when possible.
Veza understands an identity's level access to a resource in terms of raw system permissions in the provider's terms (such as AWS IAM s3:DeleteBucket
), and canonical permissions (such asDATA DELETE
). This allows Veza to answer the questions: "Who has MERGE
permission on production repositories?" and "who can read data from any resource flagged for PII compliance?".
OAA requires you to map each granular application permission (like "view ticket" or "close ticket") to its corresponding C/R/U/D permission. This enables search and audit of effective and configured access.
Manage Access
Metadata Write
Merge
Data Write
Pull
Data Read
SaaS apps tend to be role-based, and organizations that follow security best practices will typically restrict the assignment of permissions directly to users. Following standard RBAC concepts, an OAA role represents a collection of permissions which can be scoped to individual resources or specific resource types.
If permissions granted by a role only apply to specific resource types or sub-resources, create the custom permissions individually and add them to the role in a list:
Under the custom application OAA schema, users can have direct permissions and role-based permissions to resources. Modeling these role-based permission assignments will enable searches such as "show all users with the maintain
role in GitHub."
Note that “roles” in some apps actually function more like groups (lists of users), in which case they should be modeled using
local_groups
.
For payloads where permissions apply for the entire application, you can create a single custom permission for a role, containing all the associated canonical permissions:
As demonstrated in the OAA PagerDuty connector, this is a quick way to model authorization structures such as:
Account Owner
owner
Data Write, Data Read, Data Delete, Metadata Read, Metadata Write
Responder
limited_user
Data Read, Metadata Read
Observer
limited_user
Data Read, Metadata Read
Mapping OAA objects to external and federated identities
In Veza, the Identity Provider (IdP) serves as the representation of the source of an identity (human or otherwise). That identity can have access to many applications, clouds and other data sources. By connecting OAA entities to source IdP identities, Veza can show all the access for that identity. This can also enable powerful correlation queries such as finding deactivated Okta Users with active application accounts.
Veza makes these connections based on the identity information provided in the OAA payload.
Veza Supports Mapping for the following Identity Providers:
Active Directory
Azure AD
Custom IdP
Google Workspace
Okta
OneLogin
For all Identity Providers, the IdP Unique ID
and email
attributes are used to match the source identity to an OAA principal. Some entity types have additional properties usable for identity mapping:
Active Directory
Account Name
Distinguished Name
Azure AD
Principal Name
On Premises SAM Account Name
Okta
User Login
The Application Template's Local User entity represents a user within the application. That Local User can map to an Identity Provider (IdP) by setting the identity value(s) in the Local Users identities
array. Veza will use these identities to create an association between the IdP Identity and the Local User.
Setting external IdP Group identities
is also supported on Local Groups. This should be used when there are no Local User records in the application that correlate to the external user identities. Veza will create a connection between the IdP Group and the Local Group, indicating that all IdP users from that group will have the access granted to the Local Group.
Unknown identities set on users will result in a warning that the identity can not be found. The OAA Local User will still be successfully created.
Note on Identity Mapping from the IdP: You can confirm these values by finding the corresponding entity in Veza search or the data catalog and checking the identities Idp Unique Id and other fields in the details view. Identities that cannot be resolved are returned as warnings when the application payload is pushed.
Veza will automatically correlate HRIS Employee records and IdP identities based on the HRIS employee's email
property. The HRIS employee has an optional parameter for identity_id
if the required value is different from the user's email.
Python Code for the can be referenced on the Veza GitHub
GitLab Roles are assigned to users or Groups as part of a Group or Project. GitLab is an example of an application with fixed roles where the roles and behaviors are coded directly into the application. For the OAA Application Template, the corresponding Local Roles are also coded directly into the connector by reviewing the on available roles and the permissions associated with the roles. It is not always necessary to capture every Permission as part of the Local Role. Which permissions are important and how much detail is needed will be determined by the queries you intend to run, and the scope of Access Reviews that will be conducted in Veza.
Python Code for the can be referenced on the Veza GitHub
Both custom properties and can be used to add rich metadata and apply labeling strategies across entities in the Veza data catalog. Both can be viewed by checking an entity's details from tables view or Authorization Graph, and are fully available when searching and filtering results.
Veza tags can be assigned to objects in an OAA payload. One typical use case for tagging within the OAA payload is assigning using Veza SYSTEM_resource_managers
tags.
Note that while tags can be removed using the tags applied within the template are persistent: an existing tag won't be deleted when pushing a payload with a new tag or empty tag.
After the initial metadata push (which must contain the full payload), you can modify, add, or remove the domain, users, and groups without resubmitting other entities. An is enabled by setting "incremental_change": true
in the json_data
push payload, and specifying the update operation
for each entity to change.
You should represent system users using objects, even for apps that are SSO-enabled. The local user object is able to contain useful attributes such as activity status and timestamps, enabling rich search on those entities. A local user can also reference a federated identity, creating graph relationships between IdP entities and local users and groups when the payload is parsed. Veza handles these cross service connections similarly to built-in integrations such as Snowflake.
Users can also be grouped and assigned permissions with .
OAA Identity Provider Users can be connected to other IdPs by using the source_identity
property on the IdP users. For details see
Modifying custom providers using a partial OAA payload
When developing your OAA integration, whether to implement incremental updates depends on your use case. If you don't have a convenient way to track provider-side changes, it is typically easier to do a full extraction and metadata push, to not miss changes within the app or IdP.
After the initial metadata push, you can modify, add, or remove OAA entities, permissions, and properties without needing to submit the full payload each time. A first push can't be an incremental update.
An incremental update is specified by setting "incremental_change": true
in the json_data
push payload and adding an update operation
for each entity to change. Most payload objects support incremental update operations:
application, user, group, role, permission, role_assignments
domain, group, user
The operation
field indicates the change to make. Valid operation
s are:
"add"
, "modify"
, "delete"
to create, change, or remove an entity.
"add_resource"
, "delete_resource"
to modify resources in applications, permissions and role scopes.
"add_tag"
, "delete_tag"
to update a tag without altering the entity.
The object to update must contain an ID (name
or identity
) and the properties to create or modify. An error response will provide more details if an operation is invalid or unavailable.
When modifying dynamic properties, all five properties must be present.
add
and modify
can't be used on the same object. For example, to update both tags and properties on an entity, use:
Applying additional metadata to OAA entities
In addition to built-in fields such as last_login_at
, OAA supports custom-named properties for users, resources, groups, and other entities in a payload. Custom properties are validated against a set of custom property definitions as part of the JSON payload.
To use custom properties:
Include a definition of all properties as part of the payload push. The definition sets the type for the property.
Set the custom properties for each object.
If a built-in property doesn’t exist for the provider you are modeling, you can define custom properties in the OAA payload. This can enable sophisticated queries on many possible fields (such as encryption_enabled
, password_last_used_at
). Custom properties have a declared data type and are indexed and filterable, like any built-in property.
For example, you could use the custom string property "state" for an app that can be either "active," "suspended," or "disabled." If there's only one state, you could instead use a boolean ("active": "false").
Custom Properties are defined as part of the custom_property_definition
section and require a type. Typing the data allows Veza to provide a better index and search experience. For example, the TIMESTAMP
type enables date-relative filters such as "in the last 30 days."
Allowed types are NUMBER
, STRING
, STRING_LIST
, TIMESTAMP,
and BOOLEAN
.
A type
is required and permanent.
The maximum length of a string is 4096 characters.
In the Veza UI, underscores in property names are replaced by spaces, and first letters are capitalized (is_licensed
> Is Licensed).
If a custom property name collides with an existing built-in property, Veza will add the "Custom" prefix (ID
> Custom Id).
In the Query Builder API, custom properties are prefixed with custom_
in responses and must be prefixed with custom_
when used in filter statements.
Once pushed, properties and types can't be altered. You can re-submit the payload with additional custom property definitions to add new properties.
The provider must be deleted and pushed again to remove properties from a definition or change their types.
The original custom property definition is not required in future submissions but should be saved for later reference.
oaaclient
Python SDKA custom property definition sets possible properties, their types, and the application or resource type they can apply to. The following entities can have custom properties:
Custom Application
application_properties
Scoped by application_type
Custom User
local_user_properties
Custom Group
local_group_properties
Custom Role
local_role_properties
Custom Resource
resources
Scoped by resource_type
The following example shows a custom property definition for GitLab:
Properties are set on users and resources in custom_properties
:
Custom IdP Domain
domain_properties
Custom IdP User
user_properties
Custom IdP Group
group_properties
See the sample payload below for .
The following JSON example for includes a range of update operations. Note that when modifying tags, only include the identity and tags (no other properties such as manager_id
can be present).
Built-in properties (such as last_login
, created_at
, and is_active
for local users) enrich Veza graph entities with additional metadata. These built-in properties are described in the template documentation for and .
Dates must be in , which can include a timezone offset or use UTC (2021-01-01T22:47:31-07:00
, 2021-01-01T22:47:31Z
).
Property values on entities can be modified by pushing a complete payload with new custom_properties
or using operations.
Here are some example custom property definitions for the and templates.
The also supports creating and setting custom properties.