Azure DevOps
Port's Azure DevOps integration allows you to model Azure DevOps resources in your software catalog and ingest data into them.
Core support
This integration supports both Azure DevOps Services (cloud) and Azure DevOps Server (on-premises).
Note: When using the on-premises model, releases and work items are not supported due to API version differences. All other supported resources work the same as the cloud version.
Service principal authentication (via Microsoft Entra ID) is available for Azure DevOps Services (cloud) and works for both single-account and multi-account installations. Azure DevOps Server (on-premises) must continue to use a personal access token.
Prerequisites
- Single Account
- Multiple Accounts
- An Azure DevOps account with admin privileges.
- If you choose the self-hosted installation method, you will need a Kubernetes cluster on which to install the integration.
- Your Port user role is set to
Admin.
Existing installations that authenticate with a personal access token and a single organization URL continue to work without any changes. When accountMode is not set, the integration defaults to Single Account mode.
Authentication methods
The integration supports two authentication methods. Choose the one that matches your deployment:
- Personal access token (PAT): Authenticates against a single Azure DevOps organization (or a single on-premises collection). This is required for Azure DevOps Server (on-premises).
- Service principal (recommended): Uses a Microsoft Entra ID application to authenticate with your Azure DevOps organization. This is available for Azure DevOps Services (cloud).
Microsoft is retiring global personal access tokens in Azure DevOps on December 1, 2026, after which existing global PATs will stop working. For Azure DevOps Services (cloud), we recommend migrating to service principal authentication, which uses short-lived, Microsoft Entra-backed credentials. See Microsoft's announcement: Retirement of global personal access tokens in Azure DevOps.
- Service principal (recommended)
- Personal access token
Service principal authentication requires Azure DevOps integration version 0.9.0 or later.
We will create a Microsoft Entra ID application, grant it access to each Azure DevOps organization you want to sync, and provide the resulting credentials to the integration. The same flow applies whether you sync a single organization or multiple organizations from one installation.
-
Register an application in Microsoft Entra ID. Follow Register an application with the Microsoft identity platform. After registration, record the Application (client) ID and the Directory (tenant) ID from the app's Overview page.
-
Create a client secret. On the app registration, go to Certificates & secrets and create a new client secret. Copy the secret value immediately (it will not be shown again).
-
Add the service principal to each Azure DevOps organization you want to sync. Follow Use service principals and managed identities in Azure DevOps. For every target organization:
- Open the organization at
https://dev.azure.com/{organization}. - Navigate to Organization settings > Users > Add users.
- Search for the Enterprise Application's display name (the same name as the app registration you created).
- Assign an access level of Basic or higher. Stakeholder is not sufficient for repository access.
- Open the organization at
-
Grant the service principal permission on each project or repository you want to sync. Use the same Azure DevOps permission model you would apply to a user (for example, Project Settings > Permissions or Repository Settings > Security).
-
Collect the organization URLs you want to sync. Each URL must follow the format
https://dev.azure.com/{organization}. For example:https://dev.azure.com/my-orghttps://dev.azure.com/another-orgYou will pass these as a list to the integration.
Required permissions (click to expand)
- Azure DevOps does not use Microsoft Entra ID application permissions. All access control is enforced through the Azure DevOps permission system, so the app registration itself does not need any API permissions configured. See the Microsoft docs for the full explanation.
- Permissions must be granted separately inside each Azure DevOps organization you sync, using that organization's permission model.
- Each organization counts as a separate license for the service principal (no multi-organization licensing discount).
- The service principal must belong to the same Microsoft Entra tenant that each target Azure DevOps organization is connected to. Cross-tenant access requires Microsoft's documented key-vault and certificate workaround.
When syncing multiple organizations, Port processes a few at a time in parallel rather than all at once. Azure DevOps also enforces its own API rate limits separately for each organization. As a result, the more organizations you sync, the longer a full resync takes.
Once complete, you will have:
- A list of organization URLs (for example,
https://dev.azure.com/org-aandhttps://dev.azure.com/org-b). - A tenant ID.
- A client ID.
- A client secret value.
Provide these four values to the integration using the installation method you chose below.
The integration requires a personal access token to authenticate with your Azure DevOps account. Follow Microsoft's PAT guide to create one.
The token should either have admin permissions, or read permissions for each of the supported resources you want to ingest into Port.
Personal access tokens are scoped to a single organization (or a single on-premises collection). To sync multiple organizations from one installation, switch to the Multiple Accounts tab above.
- An Azure DevOps account with admin privileges in each organization you want to sync.
- If you choose the self-hosted installation method, you will need a Kubernetes cluster on which to install the integration.
- Your Port user role is set to
Admin. - All target Azure DevOps organizations must be backed by the same Microsoft Entra tenant as the service principal.
Authentication
Multi-account installations require service principal authentication. Personal access tokens are scoped to a single organization, so they cannot be used in multi-account mode.
Service principal authentication requires Azure DevOps integration version 0.9.0 or later.
We will create a Microsoft Entra ID application, grant it access to each Azure DevOps organization you want to sync, and provide the resulting credentials to the integration. The same flow applies whether you sync a single organization or multiple organizations from one installation.
-
Register an application in Microsoft Entra ID. Follow Register an application with the Microsoft identity platform. After registration, record the Application (client) ID and the Directory (tenant) ID from the app's Overview page.
-
Create a client secret. On the app registration, go to Certificates & secrets and create a new client secret. Copy the secret value immediately (it will not be shown again).
-
Add the service principal to each Azure DevOps organization you want to sync. Follow Use service principals and managed identities in Azure DevOps. For every target organization:
- Open the organization at
https://dev.azure.com/{organization}. - Navigate to Organization settings > Users > Add users.
- Search for the Enterprise Application's display name (the same name as the app registration you created).
- Assign an access level of Basic or higher. Stakeholder is not sufficient for repository access.
- Open the organization at
-
Grant the service principal permission on each project or repository you want to sync. Use the same Azure DevOps permission model you would apply to a user (for example, Project Settings > Permissions or Repository Settings > Security).
-
Collect the organization URLs you want to sync. Each URL must follow the format
https://dev.azure.com/{organization}. For example:https://dev.azure.com/my-orghttps://dev.azure.com/another-orgYou will pass these as a list to the integration.
Required permissions (click to expand)
- Azure DevOps does not use Microsoft Entra ID application permissions. All access control is enforced through the Azure DevOps permission system, so the app registration itself does not need any API permissions configured. See the Microsoft docs for the full explanation.
- Permissions must be granted separately inside each Azure DevOps organization you sync, using that organization's permission model.
- Each organization counts as a separate license for the service principal (no multi-organization licensing discount).
- The service principal must belong to the same Microsoft Entra tenant that each target Azure DevOps organization is connected to. Cross-tenant access requires Microsoft's documented key-vault and certificate workaround.
When syncing multiple organizations, Port processes a few at a time in parallel rather than all at once. Azure DevOps also enforces its own API rate limits separately for each organization. As a result, the more organizations you sync, the longer a full resync takes.
Once complete, you will have:
- A list of organization URLs (for example,
https://dev.azure.com/org-aandhttps://dev.azure.com/org-b). - A tenant ID.
- A client ID.
- A client secret value.
Provide these four values to the integration using the installation method you chose below.
Setup
Choose your preferred installation method below. Not sure which to pick? See the installation methods overview.
- Single Account
- Multiple Accounts
The prerequisites required for installation are listed below.
-
Go to the AzureDevOps Connectors page in Port.
-
Under
Select your installation method, chooseHosted by Port. -
Configure the
Installation parametersandAdvanced configurationas you wish (see below for details).
Installation parameters
Each integration requires specific parameters (such as an API token, a URL, etc.), as seen in Port's UI when installing it. Hover over the ⓘ icon next to each parameter to see more details about it.
Advanced configuration
- During the installation process each integration may have additional settings under the
Advanced configurationsection in Port's UI. Additionally, each integration has one or more settings that can be configured after installation. To do so, click on the integration's name in the Connectors page and navigate to theSettingtab. Hover over the ⓘ icon next to each setting to see more details about it.
Port secrets
Some integration settings require sensitive pieces of data, such as tokens. For these settings, Port secrets will be used, ensuring that your sensitive data is encrypted and secure.
When filling in such a setting, its value will be obscured (shown as ••••••••).
For each such setting, Port will automatically create a secret in your organization.
To see all secrets in your organization, follow these steps.
Port source IP addresses
When using this installation method, Port will make outbound calls to your 3rd-party applications from static IP addresses. You may need to add these addresses to your allowlist, in order to allow Port to interact with the integrated service:
- Europe (EU):
54.73.167.226,63.33.143.237,54.76.185.219 - United States (US):
3.234.37.33,54.225.172.136,3.225.234.99
-
Go to the Azure-DevOps Connectors page in your portal.
-
Select the
Self-hostedmethod. -
A
helmcommand will be displayed, with default values already filled out (e.g. your Port client ID, client secret, etc). Copy the command, replace the placeholders with your values, then run it in your terminal to install the integration.
See Prerequisites for the full authentication setup walkthrough.
Required parameters (always):
port.clientId- Your Port client id.port.clientSecret- Your Port client secret.port.baseUrl- Your Port API URL -https://api.port.iofor EU,https://api.us.port.iofor US.integration.eventListener.type- The event listener type. Read more about event listeners.integration.type- The integration to be installed.integration.config.accountMode- Account mode for the integration. One ofSingle Account(default) orMultiple Accounts. Determines which authentication method's parameters are required (see below).
Single-account mode supports either a personal access token or a Microsoft Entra ID service principal. Provide the parameters for exactly one of these methods. Mixing fields from both methods will cause the integration to fail on start-up.
- Service principal
- Personal access token
Required parameters for service principal authentication (cloud only):
integration.secrets.organizationUrls- A YAML or JSON list of Azure DevOps organization URLs to sync. For single-account service principal mode, provide a single-entry list, for example["https://dev.azure.com/org-a"].integration.secrets.tenantId- The Microsoft Entra ID directory (tenant) ID.integration.secrets.clientId- The Microsoft Entra ID application (client) ID.integration.secrets.clientSecret- The Microsoft Entra ID application client secret value.
Read more about service principals in Azure DevOps.
Required parameters for personal access token authentication:
integration.secrets.personalAccessToken- The personal access token used to authenticate with your Azure DevOps account.integration.secrets.organizationUrl- The URL of your Azure DevOps organization. Cloud:https://dev.azure.com/{organization}. On-premises:https://{instance}/{collection}.
Optional parameters (click to expand)
integration.secrets.isProjectsLimited- If using a project-scoped personal access token, this setting is enabled to create webhooks for individual projects. Enabled by default.integration.config.appHost(deprecated) - The host of the Port Ocean app. Used to set up the integration endpoint as the target for webhooks created in Azure DevOps.scheduledResyncInterval- The number of minutes between each resync. When not set, the integration will resync for each event listener resync event. Read more about scheduledResyncInterval.initializePortResources- Defaulttrue. When set totrue, the integration will create default blueprints and the Port app config mapping.sendRawDataExamples- Enable sending raw data examples from the third-party API to Port for testing and managing the integration mapping. Default istrue.integration.secrets.webhookSecret- Webhook secret for authenticating incoming events. Learn more.liveEvents.baseUrl- The host of the Port Ocean app. Used to set up the integration endpoint as the target for webhooks created in Azure DevOps.actionsProcessor.enabled- When set totrue, the integration will be able to process actions and automations.identityPropagation.enabled- When set totrue, workflow integration actions can run as the triggering user. RequiresactionsProcessor.enabledandliveEvents.baseUrl. See identity propagation.integration.config.identityOauthTenantId- Microsoft Entra ID tenant ID for the app registration used for identity propagation. Authorize and token URLs are derived from this value.integration.config.identityOauthClientId- Microsoft Entra ID application (client) ID used for identity propagation.integration.secrets.identityOauthClientSecret- Microsoft Entra ID application client secret used for identity propagation.integration.config.excludedTags- A list of tags used to exclude projects and resources that belong to them from syncing. For example:["restricted", "experimental"].
If you're running high volumes of live events in a self-hosted deployment and want better reliability, event durability, or horizontal scalability, you can optionally set up Port's dedicated live events infrastructure. See live events at scale for details.
Recommended resource sizes
To ensure optimal performance and avoid out-of-memory (OOM) errors, we recommend the following resources for this integration:
- CPU Limit:
800m - CPU Request:
200m - Memory Limit:
2Gi - Memory Request:
2Gi
Set resource values
helm install my-integration port-labs/port-ocean \
# ... other parameters
--set resources.limits.cpu=800m \
--set resources.limits.memory=2Gi \
--set resources.requests.cpu=200m \
--set resources.requests.memory=2Gi
- GitHub
- Jenkins
- Azure DevOps
- GitLab
- Go to the AzureDevOps Connectors page in your portal.
- Under Select your installation method, choose your desired CI/CD platform.
- Copy the workflow and replace the placeholders with your values.
Below are the available parameters and their descriptions.
| Parameter | Description | Required? | Secret?Store this value as a GitHub Actions secret |
|---|---|---|---|
port_client_id | Your Port client ID (How to get the credentials). | ✓ | ✓ |
port_client_secret | Your Port client secret (How to get the credentials). | ✓ | ✓ |
port_base_url | Your Port API URL (https://api.port.io for EU, https://api.us.port.io for US). | ✓ | ✗ |
personal_access_token | Required for PAT authentication. The personal access token used to authenticate with your Azure DevOps account. Omit when using a service principal. | ✗ | ✓ |
organization_url | Required for PAT authentication. The URL of your Azure DevOps organization. Cloud: https://dev.azure.com/{organization}. On-premises: https://{instance}/{collection}. Omit when using a service principal. | ✗ | ✗ |
organization_urls | Required for service principal authentication. A YAML or JSON list of Azure DevOps organization URLs to sync, for example ["https://dev.azure.com/org-a","https://dev.azure.com/org-b"]. | ✗ | ✗ |
tenant_id | Required for service principal authentication. The Microsoft Entra directory (tenant) ID. | ✗ | ✓ |
client_id | Required for service principal authentication. The Microsoft Entra application (client) ID. | ✗ | ✓ |
client_secret | Required for service principal authentication. The Microsoft Entra application client secret value. | ✗ | ✓ |
is_projects_limited | If using a project-scoped personal access token, this setting is enabled to create webhooks for individual projects. Enabled by default. Only applies to PAT authentication. | ✗ | ✗ |
account_mode | Optional. Account mode for the integration. Set to "Multiple Accounts" to enable multi-account mode. Defaults to "Single Account" when omitted. | ✗ | ✗ |
initialize_port_resources | Default true. When set to true, the integration will create default blueprints and the Port app config mapping. | ✗ | ✗ |
integration_identifier | The identifier of the integration that will be installed. | ✗ | ✗ |
send_raw_data_examples | Enable sending raw data examples from the third-party API to Port for testing and managing the integration mapping. Default is true. | ✗ | ✗ |
Your Jenkins agent must be able to run Docker commands.
Below are the available parameters and their descriptions.
| Parameter | Description | Required? | Secret?Store this value as a Jenkins credential (Secret Text) |
|---|---|---|---|
OCEAN__ | Your Port client ID (How to get the credentials). | ✓ | ✓ |
OCEAN__ | Your Port client secret (How to get the credentials). | ✓ | ✓ |
OCEAN__ | Your Port API URL (https://api.port.io for EU, https://api.us.port.io for US). | ✓ | ✗ |
OCEAN__ | Required for PAT authentication. The personal access token used to authenticate with your Azure DevOps account. Omit when using a service principal. | ✗ | ✓ |
OCEAN__ | Required for PAT authentication. The URL of your Azure DevOps organization. Cloud: https://dev.azure.com/{organization}. On-premises: https://{instance}/{collection}. Omit when using a service principal. | ✗ | ✗ |
OCEAN__ | Required for service principal authentication. A YAML or JSON list of Azure DevOps organization URLs to sync, for example ["https://dev.azure.com/org-a","https://dev.azure.com/org-b"]. | ✗ | ✗ |
OCEAN__ | Required for service principal authentication. The Microsoft Entra directory (tenant) ID. | ✗ | ✓ |
OCEAN__ | Required for service principal authentication. The Microsoft Entra application (client) ID. | ✗ | ✓ |
OCEAN__ | Required for service principal authentication. The Microsoft Entra application client secret value. | ✗ | ✓ |
OCEAN__ | If using a project-scoped personal access token, this setting is enabled to create webhooks for individual projects. Enabled by default. Only applies to PAT authentication. | ✗ | ✗ |
OCEAN__ | Optional. Account mode for the integration. Set to "Multiple Accounts" to enable multi-account mode. Defaults to "Single Account" when omitted. | ✗ | ✗ |
OCEAN__ | Default true. When set to true, the integration will create default blueprints and the Port app config mapping. | ✗ | ✗ |
OCEAN__ | The identifier of the integration that will be installed. | ✗ | ✗ |
OCEAN__ | Enable sending raw data examples from the third-party API to Port for testing and managing the integration mapping. Default is true. | ✗ | ✗ |
Here is an example for a Store Jenkinsfile pipeline file:Jenkins pipeline (click to expand)
OCEAN__INTEGRATION__CONFIG__ORGANIZATION_URLS as a JSON array, for example ["https://dev.azure.com/org-a","https://dev.azure.com/org-b"].
Prerequisites
- Your Azure Devops agent should be able to run docker commands. Learn more about agents here.
- You must have permissions to create and manage Azure DevOps variable groups for storing credentials.
Set up your credentials
- Create a Variable Group: Name it port-ocean-credentials.
- Store the required variables (see the table below).
- Authorize Your Pipeline:
-
Go to "Library" -> "Variable groups."
-
Find port-ocean-credentials and click on it.
-
Select "Pipeline Permissions" and add your pipeline to the authorized list.
-
Below are the available parameters and their descriptions.
| Parameter | Description | Required? | Secret?Store this value as an Azure DevOps pipeline variable |
|---|---|---|---|
OCEAN__ | Your Port client ID (How to get the credentials). | ✓ | ✓ |
OCEAN__ | Your Port client secret (How to get the credentials). | ✓ | ✓ |
OCEAN__ | Your Port API URL (https://api.port.io for EU, https://api.us.port.io for US). | ✓ | ✗ |
OCEAN__ | Required for PAT authentication. The personal access token used to authenticate with your Azure DevOps account. Omit when using a service principal. | ✗ | ✓ |
OCEAN__ | Required for PAT authentication. The URL of your Azure DevOps organization. Cloud: https://dev.azure.com/{organization}. On-premises: https://{instance}/{collection}. Omit when using a service principal. | ✗ | ✗ |
OCEAN__ | Required for service principal authentication. A YAML or JSON list of Azure DevOps organization URLs to sync, for example ["https://dev.azure.com/org-a","https://dev.azure.com/org-b"]. | ✗ | ✗ |
OCEAN__ | Required for service principal authentication. The Microsoft Entra directory (tenant) ID. | ✗ | ✓ |
OCEAN__ | Required for service principal authentication. The Microsoft Entra application (client) ID. | ✗ | ✓ |
OCEAN__ | Required for service principal authentication. The Microsoft Entra application client secret value. | ✗ | ✓ |
OCEAN__ | If using a project-scoped personal access token, this setting is enabled to create webhooks for individual projects. Enabled by default. Only applies to PAT authentication. | ✗ | ✗ |
OCEAN__ | Optional. Account mode for the integration. Set to "Multiple Accounts" to enable multi-account mode. Defaults to "Single Account" when omitted. | ✗ | ✗ |
OCEAN__ | Default true. When set to true, the integration will create default blueprints and the Port app config mapping. | ✗ | ✗ |
OCEAN__ | The identifier of the integration that will be installed. | ✗ | ✗ |
OCEAN__ | Enable sending raw data examples from the third-party API to Port for testing and managing the integration mapping. Default is true. | ✗ | ✗ |
Here is an example for a Your Azure pipeline agent should be able to run docker commands. Store azure-pipeline.yml pipeline file:Azure pipeline (click to expand)
OCEAN__INTEGRATION__CONFIG__ORGANIZATION_URLS as a JSON array, for example ["https://dev.azure.com/org-a","https://dev.azure.com/org-b"].
- Go to the AzureDevOps Connectors page in your portal.
- Under Select your installation method, choose your desired CI/CD platform.
- Copy the workflow and replace the placeholders with your values.
Below are the available parameters and their descriptions.
| Parameter | Description | Required? | Secret?Store this value as a GitLab CI/CD variable |
|---|---|---|---|
OCEAN__ | Your Port client ID (How to get the credentials). | ✓ | ✓ |
OCEAN__ | Your Port client secret (How to get the credentials). | ✓ | ✓ |
OCEAN__ | Your Port API URL (https://api.port.io for EU, https://api.us.port.io for US). | ✓ | ✗ |
OCEAN__ | Required for PAT authentication. The personal access token used to authenticate with your Azure DevOps account. Omit when using a service principal. | ✗ | ✓ |
OCEAN__ | Required for PAT authentication. The URL of your Azure DevOps organization. Cloud: https://dev.azure.com/{organization}. On-premises: https://{instance}/{collection}. Omit when using a service principal. | ✗ | ✗ |
OCEAN__ | Required for service principal authentication. A YAML or JSON list of Azure DevOps organization URLs to sync, for example ["https://dev.azure.com/org-a","https://dev.azure.com/org-b"]. | ✗ | ✗ |
OCEAN__ | Required for service principal authentication. The Microsoft Entra directory (tenant) ID. | ✗ | ✓ |
OCEAN__ | Required for service principal authentication. The Microsoft Entra application (client) ID. | ✗ | ✓ |
OCEAN__ | Required for service principal authentication. The Microsoft Entra application client secret value. | ✗ | ✓ |
OCEAN__ | If using a project-scoped personal access token, this setting is enabled to create webhooks for individual projects. Enabled by default. Only applies to PAT authentication. | ✗ | ✗ |
OCEAN__ | Optional. Account mode for the integration. Set to "Multiple Accounts" to enable multi-account mode. Defaults to "Single Account" when omitted. | ✗ | ✗ |
OCEAN__ | Default true. When set to true, the integration will create default blueprints and the Port app config mapping. | ✗ | ✗ |
OCEAN__ | The identifier of the integration that will be installed. | ✗ | ✗ |
OCEAN__ | Enable sending raw data examples from the third-party API to Port for testing and managing the integration mapping. Default is true. | ✗ | ✗ |
The prerequisites required for installation are listed below.
-
Go to the AzureDevOps Connectors page in Port.
-
Under
Select your installation method, chooseHosted by Port. -
Configure the
Installation parametersandAdvanced configurationas you wish (see below for details).
Installation parameters
Each integration requires specific parameters (such as an API token, a URL, etc.), as seen in Port's UI when installing it. Hover over the ⓘ icon next to each parameter to see more details about it.
Advanced configuration
- During the installation process each integration may have additional settings under the
Advanced configurationsection in Port's UI. Additionally, each integration has one or more settings that can be configured after installation. To do so, click on the integration's name in the Connectors page and navigate to theSettingtab. Hover over the ⓘ icon next to each setting to see more details about it.
Port secrets
Some integration settings require sensitive pieces of data, such as tokens. For these settings, Port secrets will be used, ensuring that your sensitive data is encrypted and secure.
When filling in such a setting, its value will be obscured (shown as ••••••••).
For each such setting, Port will automatically create a secret in your organization.
To see all secrets in your organization, follow these steps.
Port source IP addresses
When using this installation method, Port will make outbound calls to your 3rd-party applications from static IP addresses. You may need to add these addresses to your allowlist, in order to allow Port to interact with the integrated service:
- Europe (EU):
54.73.167.226,63.33.143.237,54.76.185.219 - United States (US):
3.234.37.33,54.225.172.136,3.225.234.99
-
Go to the Azure-DevOps Connectors page in your portal.
-
Select the
Self-hostedmethod. -
A
helmcommand will be displayed, with default values already filled out (e.g. your Port client ID, client secret, etc). Copy the command, replace the placeholders with your values, then run it in your terminal to install the integration.
See Prerequisites for the full authentication setup walkthrough.
Required parameters (always):
port.clientId- Your Port client id.port.clientSecret- Your Port client secret.port.baseUrl- Your Port API URL -https://api.port.iofor EU,https://api.us.port.iofor US.integration.eventListener.type- The event listener type. Read more about event listeners.integration.type- The integration to be installed.integration.config.accountMode- Set toMultiple Accounts.
Required parameters for multi-account service principal authentication (cloud only):
integration.secrets.organizationUrls- A YAML or JSON list of Azure DevOps organization URLs to sync, for example["https://dev.azure.com/org-a","https://dev.azure.com/org-b"].integration.secrets.tenantId- The Microsoft Entra ID directory (tenant) ID.integration.secrets.clientId- The Microsoft Entra ID application (client) ID.integration.secrets.clientSecret- The Microsoft Entra ID application client secret value.
All target organizations must be backed by the same Microsoft Entra tenant as the service principal. Read more about service principals in Azure DevOps.
Optional parameters (click to expand)
integration.config.appHost(deprecated) - The host of the Port Ocean app. Used to set up the integration endpoint as the target for webhooks created in Azure DevOps.scheduledResyncInterval- The number of minutes between each resync. When not set, the integration will resync for each event listener resync event. Read more about scheduledResyncInterval.initializePortResources- Defaulttrue. When set totrue, the integration will create default blueprints and the Port app config mapping.sendRawDataExamples- Enable sending raw data examples from the third-party API to Port for testing and managing the integration mapping. Default istrue.integration.secrets.webhookSecret- Webhook secret for authenticating incoming events. Learn more.liveEvents.baseUrl- The host of the Port Ocean app. Used to set up the integration endpoint as the target for webhooks created in Azure DevOps.integration.config.excludedTags- A list of tags used to exclude projects and resources that belong to them from syncing. For example:["restricted", "experimental"].
If you're running high volumes of live events in a self-hosted deployment and want better reliability, event durability, or horizontal scalability, you can optionally set up Port's dedicated live events infrastructure. See live events at scale for details.
Recommended resource sizes
To ensure optimal performance and avoid out-of-memory (OOM) errors, we recommend the following resources for this integration:
- CPU Limit:
800m - CPU Request:
200m - Memory Limit:
2Gi - Memory Request:
2Gi
Set resource values
helm install my-integration port-labs/port-ocean \
# ... other parameters
--set resources.limits.cpu=800m \
--set resources.limits.memory=2Gi \
--set resources.requests.cpu=200m \
--set resources.requests.memory=2Gi
- GitHub
- Jenkins
- Azure DevOps
- GitLab
- Go to the AzureDevOps Connectors page in your portal.
- Under Select your installation method, choose your desired CI/CD platform.
- Copy the workflow and replace the placeholders with your values.
Below are the available parameters and their descriptions.
| Parameter | Description | Required? | Secret?Store this value as a GitHub Actions secret |
|---|---|---|---|
port_client_id | Your Port client ID (How to get the credentials). | ✓ | ✓ |
port_client_secret | Your Port client secret (How to get the credentials). | ✓ | ✓ |
port_base_url | Your Port API URL (https://api.port.io for EU, https://api.us.port.io for US). | ✓ | ✗ |
account_mode | Required for multi-account mode. Set to "multi-accounts". | ✓ | ✓ |
organization_urls | Required. A YAML or JSON list of Azure DevOps organization URLs to sync, for example ["https://dev.azure.com/org-a","https://dev.azure.com/org-b"]. | ✓ | ✓ |
tenant_id | Required. The Microsoft Entra directory (tenant) ID. | ✓ | ✓ |
client_id | Required. The Microsoft Entra application (client) ID. | ✓ | ✓ |
client_secret | Required. The Microsoft Entra application client secret value. | ✓ | ✓ |
initialize_port_resources | Default true. When set to true, the integration will create default blueprints and the Port app config mapping. | ✗ | ✗ |
integration_identifier | The identifier of the integration that will be installed. | ✗ | ✗ |
send_raw_data_examples | Enable sending raw data examples from the third-party API to Port for testing and managing the integration mapping. Default is true. | ✗ | ✗ |
Your Jenkins agent must be able to run Docker commands.
Below are the available parameters and their descriptions.
| Parameter | Description | Required? | Secret?Store this value as a Jenkins credential (Secret Text) |
|---|---|---|---|
OCEAN__ | Your Port client ID (How to get the credentials). | ✓ | ✓ |
OCEAN__ | Your Port client secret (How to get the credentials). | ✓ | ✓ |
OCEAN__ | Your Port API URL (https://api.port.io for EU, https://api.us.port.io for US). | ✓ | ✗ |
OCEAN__ | Required for multi-account mode. Set to "multi-accounts". | ✓ | ✓ |
OCEAN__ | Required. A YAML or JSON list of Azure DevOps organization URLs to sync, for example ["https://dev.azure.com/org-a","https://dev.azure.com/org-b"]. | ✓ | ✓ |
OCEAN__ | Required. The Microsoft Entra directory (tenant) ID. | ✓ | ✓ |
OCEAN__ | Required. The Microsoft Entra application (client) ID. | ✓ | ✓ |
OCEAN__ | Required. The Microsoft Entra application client secret value. | ✓ | ✓ |
OCEAN__ | Default true. When set to true, the integration will create default blueprints and the Port app config mapping. | ✗ | ✗ |
OCEAN__ | The identifier of the integration that will be installed. | ✗ | ✗ |
OCEAN__ | Enable sending raw data examples from the third-party API to Port for testing and managing the integration mapping. Default is true. | ✗ | ✗ |
Here is an example for a Store Jenkinsfile pipeline file:Jenkins pipeline (click to expand)
OCEAN__INTEGRATION__CONFIG__ORGANIZATION_URLS as a JSON array, for example ["https://dev.azure.com/org-a","https://dev.azure.com/org-b"].
Prerequisites
- Your Azure Devops agent should be able to run docker commands. Learn more about agents here.
- You must have permissions to create and manage Azure DevOps variable groups for storing credentials.
Set up your credentials
- Create a Variable Group: Name it port-ocean-credentials.
- Store the required variables (see the table below).
- Authorize Your Pipeline:
-
Go to "Library" -> "Variable groups."
-
Find port-ocean-credentials and click on it.
-
Select "Pipeline Permissions" and add your pipeline to the authorized list.
-
Below are the available parameters and their descriptions.
| Parameter | Description | Required? | Secret?Store this value as an Azure DevOps pipeline variable |
|---|---|---|---|
OCEAN__ | Your Port client ID (How to get the credentials). | ✓ | ✓ |
OCEAN__ | Your Port client secret (How to get the credentials). | ✓ | ✓ |
OCEAN__ | Your Port API URL (https://api.port.io for EU, https://api.us.port.io for US). | ✓ | ✗ |
OCEAN__ | Required for multi-account mode. Set to "multi-accounts". | ✓ | ✓ |
OCEAN__ | Required. A YAML or JSON list of Azure DevOps organization URLs to sync, for example ["https://dev.azure.com/org-a","https://dev.azure.com/org-b"]. | ✓ | ✓ |
OCEAN__ | Required. The Microsoft Entra directory (tenant) ID. | ✓ | ✓ |
OCEAN__ | Required. The Microsoft Entra application (client) ID. | ✓ | ✓ |
OCEAN__ | Required. The Microsoft Entra application client secret value. | ✓ | ✓ |
OCEAN__ | Default true. When set to true, the integration will create default blueprints and the Port app config mapping. | ✗ | ✗ |
OCEAN__ | The identifier of the integration that will be installed. | ✗ | ✗ |
OCEAN__ | Enable sending raw data examples from the third-party API to Port for testing and managing the integration mapping. Default is true. | ✗ | ✗ |
Here is an example for a Your Azure pipeline agent should be able to run docker commands. Store azure-pipeline.yml pipeline file:Azure pipeline (click to expand)
OCEAN__INTEGRATION__CONFIG__ORGANIZATION_URLS as a JSON array, for example ["https://dev.azure.com/org-a","https://dev.azure.com/org-b"].
- Go to the AzureDevOps Connectors page in your portal.
- Under Select your installation method, choose your desired CI/CD platform.
- Copy the workflow and replace the placeholders with your values.
Below are the available parameters and their descriptions.
| Parameter | Description | Required? | Secret?Store this value as a GitLab CI/CD variable |
|---|---|---|---|
OCEAN__ | Your Port client ID (How to get the credentials). | ✓ | ✓ |
OCEAN__ | Your Port client secret (How to get the credentials). | ✓ | ✓ |
OCEAN__ | Your Port API URL (https://api.port.io for EU, https://api.us.port.io for US). | ✓ | ✗ |
OCEAN__ | Required for multi-account mode. Set to "multi-accounts". | ✓ | ✓ |
OCEAN__ | Required. A YAML or JSON list of Azure DevOps organization URLs to sync, for example ["https://dev.azure.com/org-a","https://dev.azure.com/org-b"]. | ✓ | ✓ |
OCEAN__ | Required. The Microsoft Entra directory (tenant) ID. | ✓ | ✓ |
OCEAN__ | Required. The Microsoft Entra application (client) ID. | ✓ | ✓ |
OCEAN__ | Required. The Microsoft Entra application client secret value. | ✓ | ✓ |
OCEAN__ | Default true. When set to true, the integration will create default blueprints and the Port app config mapping. | ✗ | ✗ |
OCEAN__ | The identifier of the integration that will be installed. | ✗ | ✗ |
OCEAN__ | Enable sending raw data examples from the third-party API to Port for testing and managing the integration mapping. Default is true. | ✗ | ✗ |
Configuration
Port integrations use a YAML mapping block to ingest data from the third-party api into Port.
The mapping makes use of the JQ JSON processor to select, modify, concatenate, transform and perform other operations on existing fields and values from the integration API.
Default mapping configuration
This is the default mapping configuration for this integration:
Default mapping configuration (click to expand)
deleteDependentEntities: true
createMissingRelatedEntities: true
enableMergeEntity: true
resources:
- kind: project
selector:
query: 'true'
defaultTeam: 'false'
port:
entity:
mappings:
identifier: .id | gsub(" "; "")
blueprint: '"azureDevopsProject"'
title: .name
properties:
state: .state
revision: .revision
visibility: .visibility
defaultTeam: .defaultTeam.name
link: .url | gsub("_apis/projects/"; "")
- kind: repository
selector:
query: 'true'
includedFiles:
- README.md
port:
entity:
mappings:
identifier: .id
title: .name
blueprint: '"azureDevopsRepository"'
properties:
url: .remoteUrl
readme: .__includedFiles["README.md"]
id: .id
last_activity: .project.lastUpdateTime
relations:
project: .project.id | gsub(" "; "")
- kind: repository-policy
selector:
query: .type.displayName=="Minimum number of reviewers"
port:
entity:
mappings:
identifier: .__repository.id
blueprint: '"azureDevopsRepository"'
properties:
minimumApproverCount: .settings.minimumApproverCount
- kind: repository-policy
selector:
query: .type.displayName=="Work item linking"
port:
entity:
mappings:
identifier: .__repository.id
blueprint: '"azureDevopsRepository"'
properties:
workItemLinking: .isEnabled and .isBlocking
- kind: user
selector:
query: 'true'
port:
entity:
mappings:
identifier: .id
title: .user.displayName
blueprint: '"azureDevopsMember"'
properties:
url: .user.url
email: .user.mailAddress
- kind: pull-request
selector:
query: 'true'
port:
entity:
mappings:
identifier: .repository.id + "/" + (.pullRequestId | tostring)
blueprint: '"azureDevopsPullRequest"'
properties:
status: .status
createdAt: .creationDate
leadTimeHours: (.creationDate as $createdAt | .status as $status | .closedDate as $closedAt | ($createdAt | sub("\\..*Z$"; "Z") | strptime("%Y-%m-%dT%H:%M:%SZ") | mktime) as $createdTimestamp | ($closedAt | if . == null then null else sub("\\..*Z$"; "Z") | strptime("%Y-%m-%dT%H:%M:%SZ") | mktime end) as $closedTimestamp | if $status == "completed" and $closedTimestamp != null then (((($closedTimestamp - $createdTimestamp) / 3600) * 100 | floor) / 100) else null end)
relations:
repository: .repository.id
service:
combinator: '"and"'
rules:
- operator: '"="'
property: '"ado_repository_id"'
value: .repository.id
creator:
combinator: '"and"'
rules:
- operator: '"="'
property: '"$identifier"'
value: .createdBy.uniqueName
reviewers:
combinator: '"and"'
rules:
- operator: '"in"'
property: '"$identifier"'
value: '[.reviewers[].uniqueName]'
azure_devops_reviewers: '[.reviewers[].id]'
azure_devops_creator: .createdBy.id
- kind: build
selector:
query: "true"
port:
entity:
mappings:
identifier: .__project.id + "/" + (.id | tostring) | gsub(" "; "")
title: .buildNumber
blueprint: '"azureDevopsBuild"'
properties:
status: .status
result: .result
queueTime: .queueTime
startTime: .startTime
finishTime: .finishTime
definitionName: .definition.name
requestedFor: .requestedFor.displayName
link: ._links.web.href
relations:
pipeline: .__project.id + "/" + (.definition.id | tostring)
- kind: pipeline-stage
selector:
query: 'true'
port:
entity:
mappings:
identifier: .__project.id + "/" + (.__build.id | tostring) + "/" + (.id | tostring) | gsub(" "; "")
title: .name
blueprint: '"azureDevopsPipelineStage"'
properties:
state: .state
result: .result
startTime: .startTime
finishTime: .finishTime
stageType: .type
relations:
build: (.__project.id + "/" + (.__build.id | tostring)) | gsub(" "; "")
pipelineRun: .__project.id + "/" + (.__build.id | tostring) | gsub(" "; "")
- kind: pipeline-run
selector:
query: 'true'
port:
entity:
mappings:
identifier: .__project.id + "/" + (.__pipeline.id | tostring) + "/" + (.id | tostring) | gsub(" "; "")
blueprint: '"azureDevopsPipelineRun"'
properties:
state: .state
result: .result
createdDate: .createdDate
finishedDate: .finishedDate
pipelineName: .pipeline.name
relations:
pipeline: .__project.id + "/" + (.__pipeline.id | tostring)
- kind: environment
selector:
query: 'true'
port:
entity:
mappings:
identifier: .project.id + "/" + (.id | tostring) | gsub(" "; "")
title: .name | tostring
blueprint: '"azureDevopsEnvironment"'
properties:
description: .description
createdOn: .createdOn
lastModifiedOn: .lastModifiedOn
relations: {}
- kind: release-deployment
selector:
query: 'true'
includeRelease: true
port:
entity:
mappings:
identifier: .releaseDefinition.projectReference.id + "/" + (.release.id | tostring) + "/" + (.id | tostring) | gsub(" "; "")
title: .release.name + "-" + (.id | tostring) | gsub(" "; "")
blueprint: '"azureDevopsReleaseDeployment"'
properties:
status: .deploymentStatus
url: .url
reason: .reason
startedOn: .startedOn
completedOn: .completedOn
requestedBy: .requestedBy.displayName
operationStatus: .operationStatus
environment: .releaseEnvironment.name
relations:
release: .releaseDefinition.projectReference.id + "/" + (.release.id | tostring) | gsub(" "; "")
- kind: pipeline-deployment
selector:
query: 'true'
port:
entity:
mappings:
identifier: .__project.id + "/" + (.environmentId | tostring) + "/" + (.id | tostring) | gsub(" "; "")
title: .requestIdentifier | tostring
blueprint: '"azureDevopsPipelineDeployment"'
properties:
planType: .planType
stageName: .stageName
jobName: .jobName
result: .result
startTime: .startTime
finishTime: .finishTime
relations:
environment: .__project.id + "/" + (.environmentId | tostring) | gsub(" "; "")
build: .__project.id + "/" + (.owner.id | tostring) | gsub(" "; "")
Multi-organization mapping
When the integration runs in multi-organization mode, every ingested entity is enriched with two extra fields that you can reference in JQ:
__organizationUrl: the full URL of the Azure DevOps organization the entity came from (for example,https://dev.azure.com/org-a).__organizationName: the short organization name extracted from that URL (for example,org-a).
Use these fields to disambiguate entities that share an ID across organizations, or to surface the source organization on each entity.
Example multi-organization mapping (click to expand)
resources:
- kind: project
selector:
query: 'true'
port:
entity:
mappings:
identifier: .__organizationName + "/" + (.id | gsub(" "; ""))
blueprint: '"azureDevopsProject"'
title: .__organizationName + " / " + .name
properties:
organization: .__organizationName
organizationUrl: .__organizationUrl
state: .state
visibility: .visibility
- kind: repository
selector:
query: 'true'
port:
entity:
mappings:
identifier: .__organizationName + "/" + .id
title: .__organizationName + " / " + .name
blueprint: '"azureDevopsRepository"'
properties:
url: .remoteUrl
organization: .__organizationName
organizationUrl: .__organizationUrl
relations:
project: .__organizationName + "/" + (.project.id | gsub(" "; ""))
The default mapping above continues to work for single-organization installations without any changes. Add the snippet above only if you use the service principal authentication method and sync multiple organizations.
Mapping & selectors per resource
Use the explorer below to view sample payloads and the resulting Port entities for each resource type. For additional resources and advanced configurations, see the examples page.
- kind: project
selector:
query: 'true'
defaultTeam: 'false'
port:
entity:
mappings:
identifier: .id | gsub(" "; "")
blueprint: '"azureDevopsProject"'
title: .name
properties:
state: .state
revision: .revision
visibility: .visibility
defaultTeam: .defaultTeam.name
link: .url | gsub("_apis/projects/"; "")
{
"id": "fd029361-7854-4cdd-8ace-bb033fca399c",
"name": "Port Integration",
"description": "Ocean integration project",
"url": "[REDACTED]/_apis/projects/fd029361-7854-4cdd-8ace-bb033fca399c",
"state": "wellFormed",
"revision": 21,
"_links": {
"self": {
"href": "[REDACTED]/_apis/projects/fd029361-7854-4cdd-8ace-bb033fca399c"
},
"collection": {
"href": "[REDACTED]/_apis/projectCollections/a7db27e5-15a1-4e84-aca5-3de8874e5466"
},
"web": {
"href": "[REDACTED]/Port Integration"
}
},
"visibility": "private",
"defaultTeam": {
"id": "da84d6cf-fc6f-4a3a-b9f1-eccaf320589c",
"name": "Port Integration Team",
"url": "[REDACTED]/_apis/projects/fd029361-7854-4cdd-8ace-bb033fca399c/teams/da84d6cf-fc6f-4a3a-b9f1-eccaf320589c"
},
"lastUpdateTime": "2023-11-14T07:24:17.213Z"
}
{
"identifier": "fd029361-7854-4cdd-8ace-bb033fca399c",
"title": "Port Integration",
"blueprint": "azureDevopsProject",
"properties": {
"state": "wellFormed",
"revision": 21,
"visibility": "private",
"defaultTeam": "Port Integration Team",
"link": "[REDACTED]/fd029361-7854-4cdd-8ace-bb033fca399c"
}
}
Below are the supported selectors for this resource. Use them under the selector key in your integration mapping configuration to control which resources are returned from the API.
| Selector | Type | Description |
|---|---|---|
exportEnvVariables | array | Environment variable names whose values should be included in lakehouse ingest payloads for DSP processing. |
defaultTeam | boolean | If set to true, it ingests default team for each project to Port. This causes latency while syncing the entities to Port. Default value is false. Default: false. |
To connect work items to area paths (and optionally teams), see Connect work items and teams to area paths.
Set up live events
This integration supports live events, allowing real-time updates to your software catalog without waiting for the next scheduled sync.
Note that different events are supported depending on the resource type.
git.pullrequest.createdgit.pullrequest.updatedgit.pushgit.repo.createdworkitem.createdworkitem.updatedworkitem.commentedworkitem.deletedworkitem.restoredms.vss-pipelines.run-state-changed-eventms.vss-pipelinechecks-events.approval-completedms.vss-pipelinechecks-events.approval-pendingms.vss-pipelines.stage-state-changed-eventms.vss-pipelinechecks-events.check-updated-eventms.vss-pipelines.job-state-changed-eventbuild.completems.vss-alerts.alert-created-eventms.vss-alerts.alert-state-changed-eventms.vss-alerts.alert-updated-eventms.vss-release.release-created-eventms.vss-release.release-abandoned-eventms.vss-release.deployment-started-eventms.vss-release.deployment-completed-event- Hosted by Port
- Self-hosted
Live events base URL
For integrations installed using the Hosted by Port method, you can obtain the live events base URL from the Get an integration API. The response includes liveEventsUuid and liveEventsIngestHostname in the appSpec section.
Call the endpoint with your integration's identifier:
curl -X GET \
'https://api.port.io/v1/integration/<INTEGRATION_IDENTIFIER>' \
-H 'Authorization: Bearer <PORT_ACCESS_TOKEN>'
The port_region, port.baseUrl, portBaseUrl, port_base_url and OCEAN__PORT__BASE_URL parameters select which Port API instance to use:
- EU (app.port.io) →
https://api.port.io - US (app.us.port.io) →
https://api.us.port.io
In the response, look for the following fields under spec.appSpec:
{
"spec": {
"appSpec": {
"liveEventsUuid": "abcdefghijk",
"liveEventsIngestHostname": "ingest.ocean.getport.io"
}
}
}
Combine them to build the live events base URL:
https://<liveEventsIngestHostname>/live-events/<liveEventsUuid>
For example, with the values above, the live events base URL is:
https://ingest.ocean.getport.io/live-events/abcdefghijk
This is the same URL configured for the integration.
BaseUrl & webhook configuration
To enable real-time updates of the data in your software catalog, you need to define the liveEvents.baseUrl parameter.
This parameter should be set to the URL of your Azure DevOps integration instance, which needs to have the option to setup webhooks via HTTP requests/receive HTTP requests, so ensure the network is configured accordingly.
- If Azure DevOps and the integration are in the same cluster/network: Use an internal URL (e.g., a Kubernetes service DNS name).
For Kubernetes deployments, create a service to expose the integration pod and use the service URL asliveEvents.baseUrl. If both the source system and integration are in the same cluster, an internal ClusterIP service is sufficient. - If Azure DevOps is external to the integration's network: The integration must be exposed via an ingress, load balancer, or public URL that Azure DevOps can reach.
If you're running high volumes of live events in a self-hosted deployment and want better reliability, event durability, or horizontal scalability, you can optionally set up Port's dedicated live events infrastructure. See live events at scale for details.
If liveEvents.baseUrl is not provided, the integration will continue to function correctly. In such a configuration, to retrieve the latest information from the target system, the scheduledResyncInterval parameter has to be set, or a manual resync will need to be triggered through Port's UI.
To test webhooks or live event delivery to your local environment, expose your local pod or service to the internet using ngrok (e.g. ngrok http http://localhost:8000)
When isProjectsLimited is false, the integration creates organization-level Azure DevOps service hooks. Only the following hooks are subscribed:Organization-level hooks (click to expand)
Azure DevOps release service hooks use the rm publisher and are resolved through Azure DevOps's release host, vsrm.dev.azure.com.
Incremental sync
In addition to the standard full resync, this integration supports incremental sync for the following resource kinds:
work-itemreleasebuildrelease-deploymentpipeline-run
For incremental sync ofpipeline-run, the integration discovers completed runs via the Analytics OData API (analytics.*). Ensure the following:- Azure DevOps Services: Analytics is enabled by default. The credentials used by the integration need the View analytics permission on each project you sync. See Analytics permissions and prerequisites.
- Azure DevOps Server: Analytics must be installed or enabled for each project collection.
advanced-security-alert
Any other kind in your mapping is not fetched incrementally, and continues to be kept up to date by the full resync.
See Incremental sync for how it works, its current limitations, and how to enable it for your organization.
Capabilities
Refer to the capabilities page for optional features such as file ingestion, area path configuration, and multi-entity file parsing. See also Incremental sync above for syncing recently changed resources on a short interval.
Monitoring and sync status
To learn more about how to monitor and check the sync status of your integration, see the relevant documentation.
Examples
Refer to the examples page for practical configurations and their corresponding blueprint definitions.
Relevant Guides
For relevant guides and examples, see the guides section.
GitOps
Port's Azure DevOps integration also provides GitOps capabilities, refer to the GitOps page to learn more.
Advanced
Refer to the advanced page for advanced use cases and examples.