> ## Documentation Index
> Fetch the complete documentation index at: https://docs.endorlabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://docs.endorlabs.com/feedback

```json
{
  "path": "/setup-deployment/scm-integrations/azure-app/index",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# Deploy Endor Labs Azure DevOps App

> Get up and running with Endor Labs Azure DevOps App.

export const Diagram = ({children}) => {
  const [svg, setSvg] = useState('');
  const [error, setError] = useState(null);
  const [mounted, setMounted] = useState(false);
  const [id] = useState(() => `diagram-${Math.random().toString(36).slice(2)}`);
  const DEFAULTS = {
    theme: 'base',
    fontSize: '14px',
    fontFamily: 'inherit',
    primaryColor: '#26D07C',
    primaryTextColor: '#000000',
    primaryBorderColor: '#059669',
    secondaryColor: '#e5e7eb',
    secondaryTextColor: '#000000',
    secondaryBorderColor: '#9ca3af',
    tertiaryColor: '#e5e7eb',
    tertiaryTextColor: '#000000',
    tertiaryBorderColor: '#9ca3af',
    lineColor: '#6b7280',
    background: '#ffffff',
    edgeLabelBackground: '#f9fafb',
    clusterBkg: '#f0fdf4',
    clusterBorder: '#059669',
    nodeTextColor: '#000000',
    endorColor: '#26D07C',
    endorBorder: '#059669',
    managedColor: '#A7F3D0',
    managedBorder: '#059669',
    externalColor: '#e5e7eb',
    externalBorder: '#9ca3af'
  };
  const VAR_LINE_RE = /^(\w+):\s*(.+)$/;
  const TOKEN_RE = /\{\{(\w+)\}\}/g;
  const parseVarsBlock = raw => {
    const vars = {};
    const lines = raw.trim().split('\n');
    const diagramLines = [];
    let inVars = false;
    for (const line of lines) {
      const trimmed = line.trim();
      if (trimmed === '%%vars') {
        inVars = true;
        continue;
      }
      if (inVars && trimmed === '%%') {
        inVars = false;
        continue;
      }
      if (inVars) {
        const m = VAR_LINE_RE.exec(trimmed);
        if (m) vars[m[1]] = m[2];
      } else {
        diagramLines.push(line);
      }
    }
    return {
      vars,
      diagramLines
    };
  };
  const buildInitConfig = merged => ({
    theme: merged.theme,
    themeVariables: {
      fontSize: merged.fontSize,
      fontFamily: merged.fontFamily,
      primaryColor: merged.primaryColor,
      primaryTextColor: merged.primaryTextColor,
      primaryBorderColor: merged.primaryBorderColor,
      secondaryColor: merged.secondaryColor,
      secondaryTextColor: merged.secondaryTextColor,
      secondaryBorderColor: merged.secondaryBorderColor,
      tertiaryColor: merged.tertiaryColor,
      tertiaryTextColor: merged.tertiaryTextColor,
      tertiaryBorderColor: merged.tertiaryBorderColor,
      lineColor: merged.lineColor,
      background: merged.background,
      edgeLabelBackground: merged.edgeLabelBackground,
      clusterBkg: merged.clusterBkg,
      clusterBorder: merged.clusterBorder,
      nodeTextColor: merged.nodeTextColor
    }
  });
  const renderWithMermaid = (mermaid, fullDiagram) => {
    mermaid.initialize({
      startOnLoad: false,
      zoom: {
        enabled: false
      }
    });
    mermaid.render(id, fullDiagram).then(({svg: rendered}) => {
      setSvg(rendered);
      setError(null);
    }).catch(err => setError(err.message));
  };
  useEffect(() => {
    setMounted(true);
  }, []);
  useEffect(() => {
    if (!mounted || !children) return;
    const raw = typeof children === 'string' ? children : String(children);
    const {vars, diagramLines} = parseVarsBlock(raw);
    const merged = {
      ...DEFAULTS,
      ...vars
    };
    const diagram = diagramLines.join('\n').trim().replaceAll(TOKEN_RE, (_, key) => merged[key] || '');
    const fullDiagram = `%%{init: ${JSON.stringify(buildInitConfig(merged))}}%%\n${diagram}`;
    const existing = document.getElementById(id);
    if (existing) existing.remove();
    if (globalThis.mermaid) {
      renderWithMermaid(globalThis.mermaid, fullDiagram);
    } else {
      const script = document.createElement('script');
      script.src = 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js';
      script.onload = () => renderWithMermaid(globalThis.mermaid, fullDiagram);
      script.onerror = () => setError('Failed to load Mermaid');
      document.head.appendChild(script);
    }
  }, [mounted, children, id]);
  if (!mounted) return null;
  if (error) {
    return <pre style={{
      color: '#dc2626',
      background: '#fef2f2',
      padding: '12px',
      borderRadius: '6px',
      fontSize: '13px',
      overflowX: 'auto'
    }}>
        Diagram error: {error}
      </pre>;
  }
  if (!svg) {
    return <div style={{
      height: '200px',
      background: '#f3f4f6',
      borderRadius: '8px',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      color: '#9ca3af',
      fontSize: '14px'
    }}>
        Loading diagram...
      </div>;
  }
  return <div dangerouslySetInnerHTML={{
    __html: svg
  }} style={{
    overflowX: 'auto',
    padding: '8px 0'
  }} />;
};

Endor Labs provides an Azure DevOps App that continuously scans Azure repos in your projects for security risks. You can selectively scan your repositories for SCA, secrets, and SAST.

You can choose to configure the Azure DevOps App at the organization level or the project level. When you configure the Azure DevOps App at the organization level, Endor Labs adds all the projects under the organization and scans all the repos in the projects. When you add an Azure DevOps project, Endor Labs scans all repos within that project.

See [Manage Azure App](/setup-deployment/scm-integrations/azure-app/manage-azure-app) to learn how to manage your Azure App integration in Endor Labs.

## Managed namespaces for Azure DevOps

You need to add an Azure organization or a project to an Endor Labs namespace. Endor Labs maps organizations and projects in Azure DevOps as managed namespaces.

Managed namespaces have the following restrictions:

* You cannot delete managed namespaces.
* You cannot delete repos present within managed namespaces.
* You cannot add projects or create namespaces within managed namespaces.
* You cannot create any new Endor Labs App installation within the managed namespaces.

### Namespace structure when you add an Azure organization

When you add an Azure organization to an Endor Labs namespace, Endor Labs creates a child namespace for the organization and creates child namespaces for projects in the organization under the organization namespace. The organization namespace and project namespaces are managed namespaces. You can add multiple projects to the same Endor Labs namespace. Each project will have its own managed namespace.

If your organization name is `deerinc` and you have three projects, `buck`, `doe`, and `fawn`, Endor Labs creates four managed namespaces: `deerinc`, `buck`, `doe`, and `fawn`. The namespaces `buck`, `doe`, and `fawn` are child namespaces of the `deerinc` namespace.

The following image shows the namespace structure in Endor Labs.

<Diagram>
  {`
    graph TD

        %% Endor Labs namespace
        EN[endor-azure]

        %% Azure projects
        O1[deerinc]
        P1[buck]
        P2[doe]
        P3[fawn]

        %% connections
        EN --> O1
        O1 --> P1
        O1 --> P2
        O1 --> P3

        class EN,EN2 endor
        class O1,P1,P2,P3 managed
        classDef managed fill:#5EEAD4
    `}
</Diagram>

### Namespace structure when you add an Azure DevOps project

When you add an Azure DevOps project to an Endor Labs namespace, Endor Labs creates a child namespace for the Azure DevOps project and maps all repositories in that project to this namespace. The child namespace that maps to the Azure DevOps project is a managed namespace. The managed namespace has the name, `<organization name>-<project name>`. For example, if your organization name is `deerinc` and project name is `doe`, the managed namespace will have the name, `deerinc-doe`.

You can add multiple projects to the same Endor Labs namespace. Each project will have its own managed namespace. For example, your organization name is `deerinc`, which has three projects, `buck`,`doe`, and`fawn`. You add each project to the Endor Labs namespace, `endor-azure`.

The following image shows the namespace structure in Endor Labs.

<Diagram>
  {`
    graph TD

        %% Endor Labs namespace
        EN[endor-azure]

        %% Azure projects
        A1[deerinc-buck]
        A2[deerinc-doe]
        A3[deerinc-fawn]

        %% connections
        EN --> A1
        EN --> A2
        EN --> A3

        class EN,EN2 endor
        class A1,A2,A3 managed
        classDef managed fill:#5EEAD4
    `}
</Diagram>

To run CLI scans for a repository that is already scanned by the Endor Labs Azure DevOps App, specify the correct managed child namespace using the `-n` argument to prevent creating duplicate projects.

## Default branch detection

When Endor Labs scans a repository for the first time, it detects the default branch of the repository. The findings that are created in the scan are associated with the default branch.

### Changing the default branch

When you change the default branch in your source control system (for example, from `main` to `dev`):

* Endor Labs automatically detects the new default branch and sets that as the default reference
* The previous default branch becomes a reference branch
* Scans continue on the new default branch and the reference branch

The findings associated with the previous default branch are no longer associated with the default context reference. You can view them in the reference context.

### Renaming the default branch

When you rename the default branch in your source control system:

* Endor Labs automatically switches to the renamed branch
* Scans continue without disruption

### Adding repository versions

When you add a new repository version (for example, a `dev` branch), both the default branch and the new version are scanned by the Endor Labs App.

### Control default branch detection

You can control the default branch detection by setting the `ENDOR_SCAN_TRACK_DEFAULT_BRANCH` environment variable in a scan profile. You need to configure the project to use the scan profile. See [Configure scan profiles](/scan/scan-profiles) for more information.

By default, the environment variable is set to `true`. When set to `true`, the default branch detection is enabled, and the first branch you scan is automatically considered as the default branch.

## Prerequisites for Azure DevOps App

Ensure the following prerequisites are in place before you install the Endor Labs Azure DevOps App.

* An Azure DevOps cloud account and organization. If you don't have one, create one at [Azure DevOps](https://dev.azure.com).
* Endor Labs Azure DevOps App requires read permissions to in your projects. You can grant these permissions by providing read access to the **Code** category when you create an Azure DevOps personal access token for Endor Labs.

## Install the Azure DevOps App

To automatically scan repositories using the Azure DevOps App:

1. Sign in to Endor Labs.

2. Select **Projects** from the left sidebar and click **Add Project**.

3. Under **Namespace**, select the Endor Labs namespace for this installation.

   <Note>
     We recommend you use a [child namespace](/platform-administration/namespaces) for better organization of your projects.
   </Note>

4. From **AZURE**, select **Azure DevOps App**.

   <img src="https://mintcdn.com/endorlabs-b4795f4f/fKubUymrAaKP441f/images/setup-deployment/scm-integrations/azure/azure-devop-scan.webp?fit=max&auto=format&n=fKubUymrAaKP441f&q=85&s=918c291e0194a0fcfc6e25b6892b4a88" alt="Configure Azure DevOps App" style={{ width: '60%' }} width="1028" height="1318" data-path="images/setup-deployment/scm-integrations/azure/azure-devop-scan.webp" />

5. Enter the host URL of your Azure project.

   The URL must be in the format, `https://dev.azure.com/<ORG_NAME>/` when you add an Azure organization. When you add an Azure DevOps project, the URL must be in the format, `https://dev.azure.com/<ORG_NAME>/<PROJECT_NAME>`.

6. Enter your personal access token from Azure.

   You must have at least read permissions in the **Code** category for your Azure DevOps personal access token.

7. Click **Create Azure Installation**.

8. Under **Scanners**, select the scan types to enable.

   * **SCA**: Perform software composition analysis and discover AI models used in your repository.
   * **Secret**: Scan Azure repos for exposed secrets.
   * **SAST**: Scan your source code for weakness and generate SAST findings.

   The available scan types depend upon your license.

   <img src="https://mintcdn.com/endorlabs-b4795f4f/fKubUymrAaKP441f/images/setup-deployment/scm-integrations/azure/azure-scanner-types.webp?fit=max&auto=format&n=fKubUymrAaKP441f&q=85&s=df63c8c4d27ec03bc52420262fbe6459" alt="Azure DevOps App Scanners options" style={{ width: '60%' }} width="1020" height="1108" data-path="images/setup-deployment/scm-integrations/azure/azure-scanner-types.webp" />

9. Select **Include Disabled Repositories** to scan your archived repositories. By default, the Azure archived repositories aren't scanned.

10. Click **Start Scanning Repositories**.

Endor Labs Azure DevOps App scans your Azure repos every 24 hours and reports any new findings or changes to release versions of your code.

<Note>
  Only users with admin authorization role can create and manage installations.
</Note>

A CI scan may fail if triggered while monitoring scan from the Endor Labs Azure DevOps App is in progress. Complete the monitoring scans first to prevent conflicts.
