# CSV Upload

### Overview

Use CSV Upload to integrate identity and authorization metadata from sources that don't have built-in Veza connectors, but can export or provide data in tabular format.

You can create a CSV integration in Veza to:

* Import user and authorization data from legacy or custom applications
* Integrate with SaaS applications that support CSV exports
* Model employee access to homegrown or specialized systems
* Upload employee metadata from your HRIS as a source of identity for Lifecycle Management workflows

The integration uses the Open Authorization API (OAA) to map CSV data to supported OAA templates:

* **Application** - Models Users, Groups, Roles, and Resources across applications for a wide variety of authorization use cases. An introduction to the Application Template [can be found here](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/best-practices/using-oaa-templates.md).
* **Human Resource Information Systems (HRIS)** - Models employee information from HR sources for use with Lifecycle Management (LCM).

**Application Template** - Use Custom Applications to model business applications and access permissions:

* Models Users, Groups, Roles, and Resources across applications
* For example, you can upload user permissions from a homegrown CRM system, data store, or any other application users can access.
* [Learn more about the Application Template](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/best-practices/using-oaa-templates.md)

**HRIS Template** - Use for employee data from HR systems

* Models employee information and organizational structure
* For example, you can upload employee data for manager-based Access Reviews and automated provisioning with Lifecycle Management.

{% hint style="info" %}
**Which template should I choose?** If your CSV contains information about who can access what resources, choose **Application**. If it contains employee information like departments and managers, choose **HRIS**.
{% endhint %}

{% hint style="danger" %}
**Warning: Mapping Employment Status Properties with HRIS CSV**

When manually mapping your HRIS CSV, use only one of the following two fields: `is_active` or `employment_status` to avoid misleading data on employment type.
{% endhint %}

### When to Use CSV Integration

CSV integration is ideal for systems that export tabular data but lack\
dedicated Veza connectors:

* Legacy applications with user permission exports
* Custom business applications built in-house
* HR systems for employee lifecycle management
* Specialized industry tools without native APIs

CSV import enables modeling identity and permissions metadata for any application not natively supported by Veza, with flexible column mapping, custom properties, and support for multiple data formats.

### Adding a CSV Integration

#### Prerequisites

To create an integration from CSV, you will need:

* A CSV file containing relevant data with column headers
* Sufficient permissions in Veza (**Admin** or **OAA CSV Manager** role)
* Understanding of the data model for the source application
* A plan for mapping between CSV columns and Veza attributes

> For more information about user roles and permissions, see [Roles](/4yItIzMvkpAvMVFAamTf/administration/administration/users/roles.md).

#### Format Requirements

CSV (Comma-Separated Values) is a widely used file format that stores tabular data in plain text. Each row represents a record or a relationship between entities (e.g., User to Role), and columns represent attributes.

When importing from CSV:

1. The first row must contain column headers
2. Each column can be mapped to a specific Veza attribute or custom attribute
3. Columns can be ignored after uploading the file
4. At minimum, you must map columns for unique identifiers (such as user ID or Name) for each entity type you plan to import (e.g., Users, Groups, Roles, or Employees).

{% hint style="warning" %}
**Column Header Case Sensitivity**: Column headers must be unique regardless of case. While the mapping interface is case-sensitive and may allow you to map columns with similar names like "Email" and "email", the import process is case-insensitive and will fail if duplicate column names exist with different casing. Ensure all column headers have distinct names.
{% endhint %}

#### Create a CSV Integration

To create a new CSV integration:

1. Go to **Integrations** > **Add Integration**
2. Choose **Upload CSV** from the options
3. Upload a logo for the provider (optional) - This will appear throughout the Veza UI, including in Graph search, to identify the integration and entity types.
4. Enter an integration name
   * Use a title that uniquely identifies this integration source
   * Avoid generic terms like "application" or "CSV"
   * If you have multiple environments, consider including that in the name
5. Select a data source template (currently supports Application and HR Systems)
6. Enter template-specific information (fields will vary based on the selected template):

   **For Application Template:**

   * **Name**: A unique identifying name for this specific application instance (e.g., "Marketing CRM - Prod", "HR Portal - Dev").
   * **Type**: The general category or system type (e.g., "CRM", "DevOps Tool"). In Veza, the type appears as a prefix on entity names, e.g., *CRM User*, *DevOps Tool Role*.

   **For HR System Template:**

   * **Name**: A unique identifying name for the HR system (e.g., "Workday - Production", "HR Portal - Dev")

   * **Type**: The type of HR system (e.g., "HRIS", "ATS", "Benefits")

   * **URL**: The URL of the HR system

   > **Note:** Naming is critical for easy search in Veza. For Applications, the *Type* enables searching for all entities of that category, while the *Name* differentiates between multiple instances of the same system type.
7. Upload the CSV file - Veza will read the column headers and show them for mapping
8. Map your columns to Veza attributes (see Column Mapping section)
9. Click **Create Integration** to trigger extraction and parsing

### CSV Column Mapping

The CSV integration allows you to map columns in your file to specific Veza attributes. After uploading the CSV, Veza automatically detects all columns and presents them for mapping.

For each column, you can:

1. Select to include or exclude the column
2. Select the target entity type for mapping (available entities depend on the selected template)
3. Select the specific entity attribute to map to (only attributes applicable to the selected entity type will be shown)
4. For custom properties, specify a name and data type
5. Mark the row value as required. If a column mapping is marked required the CSV upload will be rejected if any row is missing a value in that column.

*Example: Mapping CSV columns to Application template entities and attributes*

![CSV Mapping Interface with column selection and attribute mapping options](/files/yI4LNR18MC5FXi1e4Y2m)

For more examples and detailed mapping patterns, see [CSV Import Examples](/4yItIzMvkpAvMVFAamTf/integrations/integrations/csv/csv-upload-examples.md).

Additionally, you can apply [transformations](/4yItIzMvkpAvMVFAamTf/integrations/integrations/csv/csv-transformations.md) to column data for more flexibility and additional formatting. Transformations can be used to:

* Combine columns to form a single attribute (e.g., `first_name` and `last_name` into a display name)
* Reformat data such as dates, times, and case (uppercase, lowercase)
* Apply padding, trimming, and character replacement
* Insert static values

#### Supported Entity Types and Attributes

> For all entities, an ID or Name is required. If ID is not provided, Name is automatically used as the unique identifier for the entity. Both are also supported.

The available entity types and attributes depend on the template you select. Each template supports different entity types.

{% hint style="danger" %}
**⚠️ Warning: Mapping Properties with HRIS CSV**

When manually mapping your HRIS CSV, use only one of the following two fields: is\_active or employment\_status to avoid misleading data on employment type.
{% endhint %}

**Application Template Entities**

**User Attributes**

| Attribute                | Description                                            |
| ------------------------ | ------------------------------------------------------ |
| ID                       | Unique identifier for the user                         |
| Name                     | Display name for the user                              |
| Is Active                | Boolean indicating if the user is active               |
| Created At               | Timestamp when the user was created                    |
| Last Login At            | Timestamp of the user's last login                     |
| Deactivated At           | Timestamp when the user was deactivated                |
| Password Last Changed At | Timestamp of the last password change                  |
| Email                    | User's email address                                   |
| Custom Properties        | Map any column to a custom user property (type varies) |
| Owner ID                 | Entity Owner ID to assign                              |
| Owner Type               | User node type for Entity Owner(s)                     |

**Group Attributes**

| Attribute         | Description                                             |
| ----------------- | ------------------------------------------------------- |
| ID                | Unique identifier for the group                         |
| Name              | Name of the group (supports list format)                |
| Created At        | Timestamp when the group was created                    |
| Custom Properties | Map any column to a custom group property (type varies) |
| Owner ID          | Entity Owner ID to assign                               |
| Owner Type        | User node type for Entity Owner(s)                      |

**Role Attributes**

| Attribute         | Description                                             |
| ----------------- | ------------------------------------------------------- |
| ID                | Unique identifier for the role                          |
| Name              | Name of the role (supports list format)                 |
| Permissions       | Permissions assigned to the role (supports list format) |
| Custom Properties | Map any column to a custom role property (type varies)  |
| Owner ID          | Entity Owner ID to assign                               |
| Owner Type        | User node type for Entity Owner(s)                      |

**HR System Template Entities**

**Employee Attributes**

| Attribute         | Description                                                |
| ----------------- | ---------------------------------------------------------- |
| ID                | Unique identifier for the employee                         |
| Name              | Employee name (typically full name)                        |
| Employee Number   | Alternative employee identifier                            |
| Company           | Employee's company                                         |
| First Name        | Employee's first name                                      |
| Last Name         | Employee's last name                                       |
| Preferred Name    | Employee's preferred name                                  |
| Display Full Name | Complete display name                                      |
| Canonical Name    | Standardized name format                                   |
| Username          | Employee's username                                        |
| Email             | Primary email address                                      |
| IDP ID            | Identity Provider ID                                       |
| Personal Email    | Personal email address                                     |
| Home Location     | Employee's home location                                   |
| Work Location     | Employee's work location                                   |
| Cost Center       | Cost center assignment                                     |
| Department        | Employee's department                                      |
| Managers          | Employee's manager(s) (supports list format)               |
| Groups            | Group memberships (supports list format)                   |
| Employment Status | Current employment status                                  |
| Is Active         | Boolean indicating active employment                       |
| Start Date        | Employment start date                                      |
| Termination Date  | Employment end date                                        |
| Job Title         | Employee's job title                                       |
| Employment Types  | Types of employment (supports list format)                 |
| Primary Time Zone | Employee's primary time zone                               |
| Custom Properties | Map any column to a custom employee property (type varies) |

{% hint style="warning" %}
**Manager Field Case Sensitivity**

When mapping the `Managers` or `manager_id` field in HRIS CSV imports, ensure that manager ID values are in **lowercase**. The system compares employee unique IDs to the lowercase value of the manager attribute when building manager relationships.

For example, if an employee has `employee_number: EMP001`, the manager reference for their direct reports should use `manager_id: emp001` (lowercase), not `EMP001`.
{% endhint %}

### Data Type Handling

#### Boolean Values

The following values are treated as `TRUE` (case-insensitive):

* `true`, `t`
* `yes`, `y`
* `1`
* `active`
* `enabled`

Any other value is treated as `FALSE`.

#### Timestamp Formats

Veza supports multiple timestamp formats:

* `2023-04-12T15:34:56.123456789Z` (RFC3339 with nanoseconds)
* `2006-01-02T15:04:05Z07:00` (RFC3339)
* `20060102150405` (Active Directory format)
* `2006-01-30 15:04:05Z07:00`
* `2006-01-30 15:04:05`
* `2006-01-30`
* `2006-01-30T`
* `2006-01-30T15:04:05`
* `2006-01-30T15:04:05Z`
* `1/2/2006` (MM/DD/YYYY format)

Timestamps are considered unset when the value is `never`, `null`, `none`, `false`, `0` or empty. Invalid timestamps will result in a processing error.

#### String Lists

For attributes that support lists (like Role Name List, and Group Name List), values should be comma-separated within the cell and the list enclosude by quotes `"`.

### Updating a CSV Integration

Incremental updates are not supported; you must submit the complete data set for each update.

{% hint style="danger" %}
**⚠️ Warning: Configuration Updates**

When updating the configuration fields or mappings for an existing CSV integration, changes are not reflected until after the next CSV Upload is processed. For example when updating the HRIS Type field, changing this field alone and saving the integration will not immediately change the type Veza system. Then new type will not be availble in graph or in other features such as Lifecycle Management (LCM) until after the next upload is processed.

**Required Process for changing configurations:**

1. Update the configuration fields in the integration settings
2. **Re-upload the complete CSV file** to apply the changes
3. Allow the Veza platform to complete the extraction and parse process
4. Verify that entity names are consistent across all Veza components
   {% endhint %}

#### Push new data for an existing integration

1. Find the CSV integration on the Veza **Integrations** page
2. Click on the integration name to view details
3. Under Data Sources, click **Upload CSV**
4. Select your updated CSV file and click **Upload**

#### Update mappings for an integration

1. Find the CSV integration on the Veza **Integrations** page
2. Click on the integration name to view details
3. Click **Edit**
4. In the integration configuration, click **Edit** above the table of current mappings
5. Modify your column mappings as needed
6. Click **Save Configuration** to apply the changes

### CSV Manager Role

Veza provides a limited privilege "CSV Manager" role for users that need permission to manage a CSV integration, but should not have access to other functionality in Veza.

{% hint style="warning" %}
**Early Access Feature**: The CSV Manager role is currently in early access and must be enabled by Veza support before it can be assigned to users. Contact your Customer Success Manager or submit a support request to enable this role.
{% endhint %}

Users with this role can:

* Create new CSV integrations
* Upload new CSV data
* Edit existing CSV integrations, including delete

This role can be combined with [Teams](/4yItIzMvkpAvMVFAamTf/administration/administration/users/teams.md) to further limit a user's scope. When a user with the CSV manager role is added to a non-root team, they can only manage CSV integrations assigned to their team.

### Processing Rules

* **Multiple Rows per Entity**: If the same entity (user, group, or role) appears in multiple rows, Veza processes them as follows:
  * Properties are set based on the first row where the entity ID (or Name if it is being used as the unique ID) appears
  * For subsequent rows with the same identifier, only relationship assignments are processed (for example user to group, or user to role)
  * Role permissions are the only properties that are additive across all rows
* **Ignored Columns**: Columns that are not mapped (unchecked) are ignored during processing
* **Additional Columns**: CSV files can contain more columns than are mapped - extra columns are ignored
* **Entity Identifiers**: Every entity type (user, group, role) requires an ID or Name (or both). If only one is provided, the same value is used for both fields and must be unique.
* **Identity Mapping**: When using the Application template, you can choose the column(s) used to connect external identities.

### Related Documentation

* [Open Authorization API (OAA) Templates](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/templates.md)
* [Managing Teams and Permissions](/4yItIzMvkpAvMVFAamTf/administration/administration/users/teams.md)
* [Creating Custom Dashboards](/4yItIzMvkpAvMVFAamTf/features/insights/dashboards.md)
* [Understanding the Veza Access Graph](/4yItIzMvkpAvMVFAamTf/features/search.md)
* [Automating CSV Upload](/4yItIzMvkpAvMVFAamTf/integrations/integrations/csv/csv-automation.md)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.veza.com/4yItIzMvkpAvMVFAamTf/integrations/integrations/csv.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
