[{"data":1,"prerenderedAt":813},["ShallowReactive",2],{"/en-us/blog/how-to-set-up-gitlab-saml-sso-with-google-workspace":3,"navigation-en-us":35,"banner-en-us":445,"footer-en-us":455,"blog-post-authors-en-us-Omid Khan":697,"blog-related-posts-en-us-how-to-set-up-gitlab-saml-sso-with-google-workspace":712,"blog-promotions-en-us":751,"next-steps-en-us":803},{"id":4,"title":5,"authorSlugs":6,"body":8,"categorySlug":9,"config":10,"content":14,"description":8,"extension":26,"isFeatured":11,"meta":27,"navigation":11,"path":28,"publishedDate":19,"seo":29,"stem":32,"tagSlugs":33,"__hash__":34},"blogPosts/en-us/blog/how-to-set-up-gitlab-saml-sso-with-google-workspace.yml","How To Set Up Gitlab Saml Sso With Google Workspace",[7],"omid-khan",null,"security",{"featured":11,"template":12,"slug":13},true,"BlogPost","how-to-set-up-gitlab-saml-sso-with-google-workspace",{"title":15,"description":16,"heroImage":17,"body":18,"date":19,"category":9,"authors":20,"tags":22},"How to set up GitLab SAML SSO with Google Workspace","Learn how to automate user provisioning and sync permissions with Google groups with this step-by-step guide.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1759320418/xjmqcozxzt4frx0hori3.png","Single sign-on (SSO) simplifies user authentication and improves security by allowing employees to access multiple applications with one set of credentials. For organizations using both GitLab and Google Workspace, integrating SAML-based SSO streamlines access management and ensures your teams can collaborate seamlessly.\n\nIn this guide, we'll walk through configuring SAML authentication between Google Workspace and GitLab.com, including automatic group synchronization that maps Google Workspace groups to GitLab roles. By the end, your users will be able to sign in to GitLab using their Google credentials, and their permissions will automatically reflect their Google group memberships.\n\n**Note:** This guide focuses on GitLab.com (SaaS). If you're using GitLab Self-Managed, the setup process differs slightly. Refer to the [official GitLab SAML documentation for self-managed instances](https://docs.gitlab.com/integration/saml/) for detailed instructions.\n\n## What you'll need\n\nBefore getting started, make sure you have:\n- **Google Workspace** with Super Admin access\n- **GitLab.com** with a Premium or Ultimate tier subscription\n- **Owner role** on a GitLab top-level group\n- Users already existing in Google Workspace (they'll be created in GitLab automatically on first login)\n\n## Understanding the architecture\n\nWhen you configure SAML SSO with group synchronization, here's what happens:\n\n1. **Authentication flow**: Users navigate to GitLab's SSO URL and are redirected to Google Workspace to authenticate.\n2. **SAML assertion**: After successful authentication, Google sends a SAML response containing user details and group memberships.\n3. **Automatic provisioning**: GitLab creates the user account (if needed) and assigns them to groups based on their Google group memberships.\n4. **Permission sync**: Each time users sign in, GitLab updates their group memberships and roles to match their current Google groups.\n\nThis setup provides several benefits:\n\n- **Centralized access control**: You can manage user access through Google Workspace groups.\n- **Automatic provisioning**: New users gain GitLab access on their first login.\n- **Dynamic permissions**: User roles update automatically based on group membership changes.\n- **Enhanced security**: You can leverage Google's authentication security features.\n- **Reduced administrative overhead**: There is no need to manually manage GitLab group memberships.\n\n## Part 1: Get your GitLab SAML configuration values\n\nFirst, you'll need to gather some information from GitLab that you'll use when creating the SAML application in Google Workspace. Here are the steps to take:\n\n### Step 1: Navigate to your GitLab group SAML settings\n\n1. Sign in to **GitLab.com**.\n2. Navigate to your **top-level group** (Note: SAML SSO can only be configured at the top-level group, not in subgroups).\n3. In the left sidebar, select **Settings > SAML SSO**.\n\n### Step 2: Copy the required URLs\n\nOn the SAML SSO settings page, you'll see three important URLs. Copy and save these somewhere accessible — you'll need them shortly:\n\n- **Assertion consumer service URL**: This is where Google will send SAML responses.\n  - Format: `https://gitlab.com/groups/your-group/-/saml/callback`\n\n- **Identifier**: Also called the Entity ID, this uniquely identifies your GitLab group.\n  - Format: `https://gitlab.com/groups/your-group`\n\n- **GitLab SSO URL**: This is the URL your users will use to sign in.\n  - Format: `https://gitlab.com/groups/your-group/-/saml/sso`\n\n\n\u003Cfigure>\n  \u003Cimg src=\"https://res.cloudinary.com/about-gitlab-com/image/upload/v1769090029/lrw6jbn7ussjze6lxg5o.png\" alt=\"GitLab SAML single sign-on settings\">\n  \u003Cfigcaption>\u003Cem>GitLab SAML single sign-on settings\u003C/em>\u003C/figcaption>\n\u003C/figure>\n## Part 2: Create your SAML application in Google Workspace\n\nNow you'll create a custom SAML application in Google Workspace that connects to your GitLab group.\n\n### Step 3: Access the Google Admin Console\n\n1. Open a new browser tab and sign in to the [Google Admin Console](https://admin.google.com/) with a Super Administrator account.\n2. Click the **Menu** icon (☰) in the top-left.\n3. Navigate to **Apps > Web and mobile apps**.\n4. Click **Add App > Add custom SAML app**.\n\u003Cp>\u003C/p>\n\u003Cfigure>\n  \u003Cimg src=\"https://res.cloudinary.com/about-gitlab-com/image/upload/v1769090026/c2inhqzppdbszysupjcd.png\" alt=\"Google custom SAML app\">\n  \u003Cfigcaption>\u003Cem>Google custom SAML app\u003C/em>\u003C/figcaption>\n\u003C/figure>\n\n### Step 4: Configure the application name\n\n1. In the **App name** field, enter GitLab (or your preferred name).\n2. Optionally upload a **GitLab logo** as the app icon for easy recognition.\n3. Click **Continue**.\n\n### Step 5: Download Google identity provider details\n\nOn the **Google Identity Provider details** page, you'll need to capture two pieces of information:\n\n1. **SSO URL**: Copy this URL. It tells GitLab where to send authentication requests.\n   - Example format: `https://accounts.google.com/o/saml2/idp?idpid=C1234abcd`\n\n\n2. **Certificate**: Click the **Download** button to save the certificate file.\n   - The file will be named something like: `GoogleIDPCertificate-gitlab.pem`\n   - Save this file somewhere you can easily find it. You'll need it in the next section\n\n3. Click **Continue**.\n\n### Step 6: Configure service provider details\n\nThis is where you'll use the GitLab URLs you copied in Step 2. Enter the following:\n\n| **Field** | **Value** | **Description** |\n|-----------|-----------|-----------------|\n| **ACS URL** | Your GitLab Assertion consumer service URL | Where Google sends SAML responses |\n| **Entity ID** | Your GitLab Identifier | Unique identifier for your GitLab group |\n| **Start URL** | Leave blank | Not required for this setup |\n| **Name ID format** | Select **EMAIL** | The format for the user identifier |\n| **Name ID** | Select **Basic Information > Primary Email** | The user's primary email will be used as their identifier |\n| **Signed response** | Leave unchecked | GitLab doesn't require signed responses by default |\n\n\u003Cfigure style=\"margin: 24px 0;\">\n  \u003Cimg src=\"https://res.cloudinary.com/about-gitlab-com/image/upload/v1769090028/kaui5vj14gkftbfgsbnz.png\" alt=\"GitLab SAML app details\">\n  \u003Cfigcaption>\u003Cem>GitLab SAML app details\u003C/em>\u003C/figcaption>\n\u003C/figure>\n\n\nClick **Continue** when complete.\n\n### Step 7: Configure attribute mapping\n\nAttribute mapping tells Google which user information to send to GitLab. You'll configure both basic user attributes and group membership.\n\n#### Basic attributes\n\nAdd these three attribute mappings by clicking **Add mapping** for each:\n\n| **Google Directory attribute** | **App attribute** |\n|--------------------------------|-------------------|\n| Primary email | email |\n| First name | first_name |\n| Last name | last_name |\n\n#### Group membership configuration\n\nThis is the critical configuration that enables automatic group synchronization:\n\n1. Scroll down to the **\"Group membership (optional)\"** section.\n2. Under **\"Google groups\"**, click **\"Search for a group\"**.\n3. Search for and select each Google Workspace group you want to synchronize with GitLab.\n   - You can select up to 75 groups\n   - Examples: Engineering, DevOps, Platform-Team, Security-Team\n\n4. Under **\"App attribute\"**, enter exactly: `groups`.\n5. Click **Finish**.\n\n\u003Cp>\u003C/p>\n\u003Cfigure>\n  \u003Cimg src=\"https://res.cloudinary.com/about-gitlab-com/image/upload/v1769090027/ksuebt9uoe3w5cdzsjkl.png\" alt=\"GitLab SAML app attribute mapping\">\n  \u003Cfigcaption>\u003Cem>GitLab SAML app attribute mapping\u003C/em>\u003C/figcaption>\n\u003C/figure>\n\n> **Critical**: The app attribute name **MUST** be exactly `groups` (lowercase). This is what GitLab expects to receive in the SAML response. Any other value or capitalization will prevent group synchronization from working.\n\n### Step 8: Enable the application for users\n\nYour SAML app is created but not yet enabled. To make it available to users:\n\n1. In the Google Admin Console, find your **GitLab** app in the Web and mobile apps list.\n2. Click on the app to open its details.\n3. In the left sidebar, click **User access**.\n4. Select one of the following:\n   - **ON for everyone** - Enables the app for all users in your organization\n   - **ON for some organizational units** - Select specific organizational units\n\n5. Click **Save**.\n\n**Note**: Changes can take up to 24 hours to propagate, but typically take effect within a few minutes.\n\n## Part 3: Convert the certificate to SHA-1 fingerprint format\n\nGitLab requires a SHA-1 certificate fingerprint, but Google's certificate download doesn't include this format directly. You'll need to convert it.\n\n### Step 9: Convert your certificate\n\nYou have two options for converting the certificate to the required format.\n\n#### Option 1: Online conversion tool\n\nThis is a viable method if you're comfortable using a third-party tool:\n\n1. **Locate the certificate file** you downloaded in Step 5:\n   - Check your Downloads folder\n   - The file name will be something like: `GoogleIDPCertificate-gitlab.pem`\n\n2. **Open the file** in a text editor:\n   - Mac: **Right-click > Open With > TextEdit**\n   - Windows: **Right-click > Open With > Notepad**\n   - Linux: Use your preferred text editor\n\n3. **Copy ALL contents** of the file, including the header and footer:\n\n\n  ```text\n  -----BEGIN CERTIFICATE-----\n  MIIDdDCCAlygAwIBAgIGAXqD...\n  (multiple lines of encoded text)\n  ...kE7RnF6yQ==\n  -----END CERTIFICATE-----\n  ```\n\n\n4. **Navigate to**: A SHA-1 fingerprint conversion tool. [This one](https://www.samltool.com/fingerprint.php) is a good example.\n5. **Paste the certificate content** into the text box.\n6. **Select \"SHA-1\"** from the algorithm dropdown (not SHA-256!).\n7. Click **\"Calculate Fingerprint\"**.\n8. **Copy the resulting fingerprint** - it will be in the format: `XX:XX:XX:XX:XX:...`.\n\n#### Option 2: Command-line conversion\n\nIf you prefer using the command line:\n\n**For Mac, Linux, or Windows with WSL:**\n\n\n  ```bash\n  cd ~/Downloads\n  openssl x509 -noout -fingerprint -sha1 -inform pem -in \"GoogleIDPCertificate-gitlab.pem\"\n  ```\n\n\nThe output will show:\n\n\n  ```text\n  SHA1 Fingerprint=XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX\n  ```\n\n\nCopy everything after `SHA1 Fingerprint=`.\n\n## Part 4: Complete your GitLab SAML configuration\n\nNow that you have the Google SSO URL and certificate fingerprint, you can complete the GitLab side of the configuration.\n\n### Step 10: Enter Google identity provider details\n\nReturn to your GitLab browser tab (**Settings > SAML SSO**) and do the following:\n\n1. **Identity provider SSO URL**:\n   - Paste the SSO URL you copied from Google in Step 5\n\n2. **Certificate fingerprint**:\n   - Paste the SHA-1 fingerprint you generated in Step 9\n   - Verify the format is correct: 59 characters with colons (XX:XX:XX:...)\n\n3. **Enable SAML authentication for this group**:\n   - Check this box to activate SAML SSO\n\n\u003Cp>\u003C/p>\n\u003Cfigure>\n  \u003Cimg src=\"https://res.cloudinary.com/about-gitlab-com/image/upload/v1769090027/ncoeqrdu7aahyuflrq7b.png\" alt=\"GitLab SAML Configuration with Google SAML values\">\n  \u003Cfigcaption>\u003Cem>GitLab SAML Configuration with Google SAML values\u003C/em>\u003C/figcaption>\n\u003C/figure>\n\n### Step 11: Configure security settings (recommended)\n\nFor enhanced security, consider enabling these additional options:\n\n- **\"Enforce SAML authentication for web activity for this group\"**\n  - Requires users to authenticate via SAML to access the GitLab web interface\n\n- **\"Enforce SAML authentication for Git and Dependency Proxy activity for this group\"**\n  - Requires SAML authentication for Git operations and dependency proxy access\n\nClick **Save changes** to apply your configuration.\n\n### Step 12: Test your SAML configuration\n\nBefore proceeding with group synchronization, verify that basic SAML authentication works:\n\n1. Open an incognito or private browsing window.\n2. Navigate to your GitLab SSO URL.\n   - Format: `https://gitlab.com/groups/your-group/-/saml/sso`\n\n3. You should be redirected to the Google sign-in page.\n4. Sign in with a Google Workspace account that has access to the GitLab app.\n5. After successful authentication, you should be redirected back to GitLab.\n\n**If the test succeeds**, you can proceed to configure group synchronization.\n\n**If the test fails**, check the following:\n\n- Verify the certificate fingerprint is SHA-1 format (not SHA-256).\n- Confirm the SSO URL is correct.\n- Ensure the user has access to the GitLab SAML app in Google Admin Console.\n- Check that the ACS URL and Entity ID match exactly.\n\n## Part 5: Set up SAML group synchronization\n\nNow it's time to map your Google Workspace groups to GitLab roles so that permissions are automatically managed based on group membership.\n\n### Step 13: Configure default membership role\n\nAs a security best practice, set a minimal default role for users who log in but don't belong to any mapped groups:\n\n1. In your GitLab group, navigate to **Settings > General**.\n2. Expand the **Permissions and group features** section.\n3. Under **Default membership role**, select **Minimal Access or Guest**.\n4. Click **Save changes**.\n\n\u003Cp>\u003C/p>\n\u003Cfigure>\n  \u003Cimg src=\"https://res.cloudinary.com/about-gitlab-com/image/upload/v1769097587/syi0jeaspzt9tki0w9nd.png\" alt=\"GitLab SAML Default membership setting\">\n  \u003Cfigcaption>\u003Cem>GitLab SAML Default membership setting\u003C/em>\u003C/figcaption>\n\u003C/figure>\n\n### Step 14: Create SAML group links\n\nSAML Group Links are the mappings between Google Workspace groups and GitLab roles. Here's how to create them:\n\n1. In your GitLab group, navigate to **Settings > SAML Group Links**.\n2. Click **\"Add new SAML Group Link\"**.\n\nFor each Google Workspace group you want to sync:\n\n**SAML Group Name**:\n\n- Enter the **exact name** of your Google Workspace group\n- This is **case-sensitive** and must match perfectly\n- Example: Engineering (not engineering)\n- To find the exact name: Google Admin Console > Directory > Groups\n\n**Access Level**: Select the appropriate GitLab role:\n\n- **Minimal Access** - Can see that the group exists\n- **Guest** - Can view issues and leave comments\n- **Reporter** - Can pull code, view issues, and create new issues\n- **Developer** - Can push code, create merge requests, and manage issues\n- **Maintainer** - Can manage project settings and members\n- **Owner** - Full administrative control over the group\n\n3. Click **Save**.\n4. **Repeat this process** for each Google Workspace group you want to map.\n\n**Note:** SAML group sync rules are enforced every time a user signs in. If a user's Google group membership matches a sync rule, their GitLab role will be automatically set to the configured access level, even if you've manually changed it to something different. For example, if you set up a sync rule that grants \"Maintainer\" access and then manually promote a user to \"Owner,\" they'll be automatically downgraded back to \"Maintainer\" on their next SAML sign-in.\n\n**Best practices:** To maintain custom access levels for specific users, do one of the following:\n\n - Use SAML group sync only on your top-level group and manually manage permissions in subgroups\n\n - Create separate Google groups for users who need elevated permissions\n \n - Avoid setting up sync rules that would conflict with manual role assignments\n\n\n\n\u003Cfigure>\n  \u003Cimg src=\"https://res.cloudinary.com/about-gitlab-com/image/upload/v1769090028/etjoaiuyhnqh4gnjqcha.png\" alt=\"GitLab SAML Group Links setup\">\n  \u003Cfigcaption>\u003Cem>GitLab SAML Group Links setup\u003C/em>\u003C/figcaption>\n\u003C/figure>\n### Example group mapping configuration\n\nHere's a practical example of how you might structure your group mappings:\n\n| **Google Workspace Group** | **GitLab Role** | **Purpose** |\n|----------------------------|-----------------|-------------|\n| GitLab-Admins | Owner | Full administrative access |\n| Engineering-Team | Maintainer | Can manage projects and settings |\n| Developer-Team | Developer | Can write and push code |\n| QA-Team | Developer | Can test and manage issues |\n| Contractors | Reporter | Read-only access to code |\n| All-Employees | Minimal Access | Basic visibility |\n\n### Step 15: Verify your group links\n\nAfter creating all your group links:\n\n1. Review the complete list of SAML Group Links in **Settings > SAML Group Links**.\n2. Verify each **SAML Group Name** exactly matches the corresponding Google Workspace group.\n3. Verify each **Access Level** is appropriate for the intended purpose.\n4. Check for any typos or extra spaces.\n\n## Part 6: Test the complete configuration\n\nNow it's time to test the entire setup including group synchronization.\n\n### Step 16: Test with a real user\n\nChoose a test user who meets these criteria:\n\n- Has a Google Workspace account\n- Is a member of at least one Google Workspace group you configured\n- Has the GitLab SAML app enabled in Google Admin Console\n- Ideally is not you (to ensure a realistic test)\n\nTo perform the test:\n\n1. **Open an incognito or private browsing window**\n2. **Navigate to your GitLab SSO URL**:\n   - `https://gitlab.com/groups/your-group/-/saml/sso`\n\n3. **Sign in** with the test user's Google Workspace credentials\n4. The user should be:\n   - Authenticated successfully\n   - Redirected to GitLab\n   - Automatically added to the GitLab group\n   - Assigned the appropriate role based on their Google group membership\n\n### Step 17: Verify group membership and role assignment\n\nUsing your GitLab administrator account:\n\n1. Navigate to your group in GitLab.\n2. Select **Manage > Members** from the left sidebar.\n3. Find the test user in the members list.\n4. Verify the following:\n   - User appears in the members list\n   - User has the correct **Max role** based on their Google group(s)\n   - **Source** column shows a SAML indicator\n\n\u003Cp>\u003C/p>\n\u003Cfigure>\n  \u003Cimg src=\"https://res.cloudinary.com/about-gitlab-com/image/upload/v1769090026/hiov7kiukidsiyscfesg.png\" alt=\"Verified SAML user added\">\n  \u003Cfigcaption>\u003Cem>Verified SAML user added\u003C/em>\u003C/figcaption>\n\u003C/figure>\n\n## Part 7: Configure subgroup access (optional)\n\nFor larger organizations, you may want to provide more granular access control using GitLab subgroups. SAML Group Links can be configured at any level of your group hierarchy, allowing you to map different Google Workspace groups to specific teams or projects.\n\n### Understanding GitLab's subgroup structure\n\nGitLab supports nested group hierarchies that can mirror your organizational structure:\n\n  ```text\n  acme-corp/                          ← Top-level group (SAML configured here)\n  ├── engineering/                    ← Subgroup\n  │   ├── backend/                   ← Nested subgroup\n  │   └── frontend/                  ← Nested subgroup\n  ├── marketing/                      ← Subgroup\n  └── operations/                     ← Subgroup\n  ```\n\n\n### Creating subgroups\n\nIf you need to create additional subgroups:\n\n1. Navigate to your **parent group** (e.g., acme-corp).\n2. Click the **New subgroup** button.\n3. Configure the subgroup:\n   - **Subgroup name**: Display name (e.g., Engineering)\n   - **Subgroup URL**: URL slug (e.g., engineering)\n   - **Visibility level**: Choose Private, Internal, or Public\n\n4. Click **Create subgroup**.\n5. Repeat for other subgroups as needed.\n\n### Configuring SAML group links for subgroups\nHere are the steps to configure SAML group links for subgroups.\n\n#### Add new Google groups to the SAML app (if needed)\n\nIf you're introducing new Google Workspace groups for subgroup access:\n\n1. Go to **Google Admin Console > Apps > Web and mobile apps > GitLab**.\n2. Click **SAML attribute mapping**.\n3. Scroll to **\"Group membership (optional)\"**.\n4. Add your new groups (e.g., Backend-Team, Frontend-Team).\n5. Verify the **\"App attribute\"** is still `groups`.\n6. Click **Save**.\n\n#### Map Google groups to subgroups\n\n1. **Navigate to the specific subgroup** in GitLab\n   - Example: acme-corp/engineering/backend\n\n2. Go to **Settings > SAML Group Links**.\n3. Click **\"Add new SAML Group Link\"**.\n4. Configure the mapping:\n   - **SAML Group Name**: Backend-Team (exact Google Workspace group name)\n   - **Access Level**: Developer (or your desired role)\n\n5. Click **Save**.\nRepeat this process for all subgroups and their corresponding Google groups.\n\n### Multi-level access example\n\nHere's how permissions might work across different levels:\n\n#### Top-level group: acme-corp\n\nSAML Group Links:\n\n- \"Company-Admins\" → Owner\n- \"All-Employees\" → Minimal Access\n\n#### Subgroup: acme-corp/engineering\n\nSAML Group Links:\n\n- \"Engineering-Leads\" → Owner\n- \"Engineering-Team\" → Maintainer\n\n#### Nested subgroup: acme-corp/engineering/backend\n\nSAML Group Links:\n\n- \"Backend-Leads\" → Maintainer\n- \"Backend-Team\" → Developer\n\n### How permissions inherit and combine\n\nUnderstanding permission behavior is important:\n\n- **Role calculation**: At each level, users receive the **highest role** from all their Google groups.\n- **Inheritance**: Higher permissions at parent levels flow down to child subgroups.\n- **Independence**: Each level calculates permissions based on its own group links plus inherited permissions.\n- **No limitation**: Lower permissions at parent levels do NOT restrict higher permissions at child levels.\n\n**Example scenarios**:\n\n**User A** (member of Backend-Team only):\n\n- acme-corp: Minimal Access (from \"All-Employees\" default)\n- acme-corp/engineering: Minimal Access (inherited from parent)\n- acme-corp/engineering/backend: Developer (from \"Backend-Team\" mapping)\n\n**User B** (member of Engineering-Leads and Backend-Team):\n\n- acme-corp: Minimal Access (from \"All-Employees\" default)\n- acme-corp/engineering: Owner (from \"Engineering-Leads\" mapping)\n- acme-corp/engineering/backend: Owner (inherited from parent, which is higher than Developer)\n\n## How the synchronization works\n\nUnderstanding the mechanics of SAML group synchronization helps you manage the system effectively.\n\n### Synchronization timing\n\n- **When sync occurs**: Group memberships update **every time** a user signs in via SAML.\n- **Frequency**: Changes are not continuous — they only happen at login.\n- **Direction**: Synchronization is **one-way** from Google Workspace to GitLab.\n- **First login**: User account is created automatically and groups are assigned.\n- **Subsequent logins**: Existing group memberships are updated to match current Google groups.\n\n### Role priority and combination\n\nWhen a user belongs to multiple Google Workspace groups:\n\n- GitLab evaluates **all** the user's groups at each level of the hierarchy.\n- The user receives the **highest role** from any of their groups.\n- This calculation happens independently at each level (top-level group, subgroups, etc.).\n\n**Example**:\n\n- User in \"Developers\" (Developer role) + \"Tech-Leads\" (Maintainer role) → Gets **Maintainer**\n\n### Automatic role changes\n\nThe system automatically handles membership changes:\n\n- **User added to a Google group**: Role upgraded on next login.\n- **User removed from a Google group**: Role recalculated based on remaining groups on next login.\n- **User removed from all mapped groups**: Reverts to default membership role on next login.\n- **User added to additional groups**: Gets highest role from all groups on next login.\n\n### Propagation timing\n\nBe aware of these timing considerations:\n\n- **Google Workspace changes**: Can take up to 24 hours to propagate, though usually take only a few minutes.\n- **GitLab sync**: Happens immediately when the user logs in after Google changes are live.\n- **Testing**: Have users log out and log back in to test permission changes.\n\n## Understanding user lifecycle and edge cases\n\n### What happens when you remove a user from GitLab?\n\n**Removing permissions only:** If you remove a user from GitLab projects but leave their account active and they're still in the authorized Google groups:\n\n- They keep their same account (same user ID and username)\n- When they log in via SAML, their group memberships are automatically restored\n- They regain permissions based on their current Google group memberships\n\n**Blocking the account:**\n\n- Account exists but is locked\n- User cannot log in even if in Google groups\n- Can be unblocked later, preserving all history\n\n**Deleting the account:**\n\n- Account is permanently removed\n- If user logs in again (while still in Google groups), GitLab creates a **completely new account**\n- New account has different user ID with no connection to the old one\n\n### Proper offboarding process\n\nTo permanently revoke access, follow this order:\n\n1. **Remove from Google Workspace groups** - Prevents authentication\n2. **Block in GitLab** - Prevents account recreation and preserves audit trails\n3. **Delete account (optional)** - Only if you're certain they won't return\n\n> **Critical**: Removing a user only from GitLab without removing them from Google groups means they can simply log back in and regain access.\n\n### Google group membership propagation\n\nAccording to [Google's documentation](https://support.google.com/a/answer/11143403), group membership changes can take up to 24 hours to propagate, though typically occur within minutes.\n\n### Account recreation scenarios\n\n| **Scenario** | **User still in Google groups?** | **What happens on login** |\n|--------------|----------------------------------|---------------------------|\n| Permissions removed | Yes | Same account, group memberships restored |\n| Account blocked | Yes | Login fails |\n| Account deleted | Yes | New account created with new user ID |\n| Removed from Google groups | No | Login fails at Google |\n\n## Troubleshooting common issues\n\nEven with careful configuration, you might encounter issues. Here are solutions to the most common problems.\n\n### Users not being added to groups\n\n**Symptom**: User successfully logs in via SAML but doesn't appear in any GitLab groups, or appears with only the default role.\n\n**Possible causes and solutions**:\n\n1. **Group names don't match exactly**\n   - Check spelling and capitalization in both Google Workspace and GitLab\n   - Look for extra spaces before or after group names\n   - Verify the exact name in Google Admin Console > Directory > Groups\n\n2. **User not actually in the Google group**\n   - Verify membership: Google Admin Console > Directory > Groups > [Group] > Members\n   - Remember that nested group membership might not be included\n\n3. **Groups not configured in SAML app**\n   - Verify the groups are selected in Google SAML attribute mapping\n   - Confirm \"App attribute\" is set to `groups` (lowercase)\n   - Use \"Test SAML Login\" to inspect the SAML response\n\n4. **Timing or cache issue**\n   - Wait 24 hours for Google changes to fully propagate\n   - Have the user log out of GitLab and Google completely\n   - Clear browser cache and try again\n   - User must log in via the SAML SSO URL, not regular GitLab login\n\n### User has incorrect role\n\n**Symptom**: User has access but with the wrong permission level.\n\n**Possible causes and solutions**:\n\n1. **User belongs to multiple groups**\n   - Remember: Users get the **highest** role from all their groups\n   - Check all Google groups the user belongs to\n   - Review all SAML Group Link configurations at all levels\n\n2. **SAML Group Link misconfigured**\n   - Verify the Access Level setting in Settings > SAML Group Links\n   - Check for duplicate group mappings that might conflict\n\n3. **User hasn't logged in since changes**\n   - Roles only update when users log in via SAML\n   - Have the user log out completely and log back in via the SSO URL\n\n4. **Inherited permissions from parent groups**\n   - Check SAML Group Links in parent groups\n   - Remember that higher roles at parent levels flow down to children\n\n### SAML authentication fails completely\n\n**Symptom**: Users cannot log in at all, or receive error messages during authentication.\n\n**Possible causes and solutions**:\n\n1. **Incorrect certificate fingerprint**\n   - Verify you used SHA-1 format, not SHA-256\n   - Check the fingerprint has the correct format with colons\n   - Regenerate using the online tool or OpenSSL command\n\n2. **Wrong SSO URL**\n   - Double-check the SSO URL copied from Google\n   - Ensure there are no extra spaces or characters\n\n3. **ACS URL or Entity ID mismatch**\n   - Verify the ACS URL in Google Admin Console matches GitLab exactly\n   - Confirm the Entity ID matches between both systems\n\n4. **User doesn't have app access**\n   - Check User Access settings in Google Admin Console\n   - Verify the user's organizational unit has the app enabled\n   - Confirm the app is \"ON\" for the appropriate users\n\n5. **Certificate expired**\n   - Check certificate validity dates\n   - Download a fresh certificate if needed\n\n### Groups attribute missing from SAML response\n\n**Symptom**: Users can log in but group synchronization doesn't work at all.\n\n**Possible causes and solutions**:\n\n1. **Groups not selected in Google configuration**\n   - Return to **Google Admin > Apps > GitLab > Attribute** mapping\n   - Verify groups are selected under \"Group membership\"\n   - Confirm \"App attribute\" is exactly `groups` (lowercase)\n\n2. **User not in any configured groups**\n   - Only groups the user belongs to are sent in the SAML response\n   - Add the user to at least one selected group to test\n\n3. **Configuration hasn't propagated**\n   - Wait up to 24 hours for changes to take effect\n   - Try logging out of Google Admin Console and back in\n\n4. **Typo in app attribute name**\n   - The attribute name must be exactly `groups` (lowercase)\n   - Even a capital letter or extra space will break functionality\n\n## Best practices for managing SAML group sync\n\nFollow these recommendations to maintain a secure and efficient setup.\n\n### Security best practices\n\n1. **Maintain emergency access**\n   - Keep at least one Owner account that uses password authentication (not SAML)\n   - This provides emergency access if SAML configuration breaks\n   - Store these credentials securely\n\n2. **Use least privilege principle**\n   - Set default membership to Minimal Access\n   - Only grant higher permissions through explicit group mappings\n   - Regularly review and audit group memberships\n\n3. **Enable enforcement options**\n   - Turn on \"Enforce SAML authentication\" options\n   - This prevents users from bypassing SSO\n   - Exceptions should be rare and well-documented\n\n4. **Regular security audits**\n   - Quarterly review of Google Workspace group memberships\n   - Annual review of SAML Group Link mappings\n   - Monitor GitLab audit logs for unusual access patterns\n\n## Summary and next steps\n\nCongratulations! You've successfully configured SAML SSO and automatic group synchronization between Google Workspace and GitLab. Your setup now provides:\n\n- **Seamless authentication** - Users sign in with their familiar Google Workspace credentials.\n- **Automatic provisioning** - User accounts are created on first login without manual intervention.\n- **Dynamic permissions** - Group memberships and roles update automatically based on Google Workspace groups.\n- **Centralized access control** - Manage all access through your existing Google Workspace groups.\n- **Enhanced security** - Leverage Google's authentication infrastructure and enforce consistent policies.\n- **Reduced administrative overhead** - Eliminate manual user and permission management in GitLab.\n\n### What happens now\n\nWhen users access GitLab:\n\n1. They navigate to your GitLab SSO URL.\n2. Authenticate using their Google Workspace credentials.\n3. Get automatically added to appropriate GitLab groups.\n4. Receive permissions based on their Google group memberships.\n5. Their permissions update every time they sign in.\n\n### Additional resources\n\n- [GitLab SAML SSO Documentation](https://docs.gitlab.com/ee/user/group/saml_sso/)\n- [GitLab SAML Group Sync Documentation](https://docs.gitlab.com/ee/user/group/saml_sso/group_sync.html)\n- [Google Workspace SAML App Setup](https://support.google.com/a/answer/6087519)\n- [SAML Certificate Fingerprint Tool](https://www.samltool.com/fingerprint.php)\n\n## Related article\n* [How-to: GitLab Single Sign-on with SAML, SCIM, and Azure's Entra ID](https://about.gitlab.com/blog/how-to-gitlab-single-sign-on-with-saml-scim-and-azures-entra-id/)","2026-01-27",[21],"Omid Khan",[9,23,24,25],"tutorial","product","google","yml",{},"/en-us/blog/how-to-set-up-gitlab-saml-sso-with-google-workspace",{"config":30,"title":15,"description":16},{"noIndex":31},false,"en-us/blog/how-to-set-up-gitlab-saml-sso-with-google-workspace",[9,23,24,25],"YRrxqgA4t2__ptKowdH-TEa8Ws9myTyds-cJf8PgaNo",{"data":36},{"logo":37,"freeTrial":42,"sales":47,"login":52,"items":57,"search":365,"minimal":396,"duo":415,"switchNav":424,"pricingDeployment":435},{"config":38},{"href":39,"dataGaName":40,"dataGaLocation":41},"/","gitlab logo","header",{"text":43,"config":44},"Get free trial",{"href":45,"dataGaName":46,"dataGaLocation":41},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":48,"config":49},"Talk to sales",{"href":50,"dataGaName":51,"dataGaLocation":41},"/sales/","sales",{"text":53,"config":54},"Sign in",{"href":55,"dataGaName":56,"dataGaLocation":41},"https://gitlab.com/users/sign_in/","sign in",[58,85,180,185,286,346],{"text":59,"config":60,"cards":62},"Platform",{"dataNavLevelOne":61},"platform",[63,69,77],{"title":59,"description":64,"link":65},"The intelligent orchestration platform for DevSecOps",{"text":66,"config":67},"Explore our Platform",{"href":68,"dataGaName":61,"dataGaLocation":41},"/platform/",{"title":70,"description":71,"link":72},"GitLab Duo Agent Platform","Agentic AI for the entire software lifecycle",{"text":73,"config":74},"Meet GitLab Duo",{"href":75,"dataGaName":76,"dataGaLocation":41},"/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":78,"description":79,"link":80},"Why GitLab","See the top reasons enterprises choose GitLab",{"text":81,"config":82},"Learn more",{"href":83,"dataGaName":84,"dataGaLocation":41},"/why-gitlab/","why gitlab",{"text":86,"left":11,"config":87,"link":89,"lists":93,"footer":162},"Product",{"dataNavLevelOne":88},"solutions",{"text":90,"config":91},"View all Solutions",{"href":92,"dataGaName":88,"dataGaLocation":41},"/solutions/",[94,118,141],{"title":95,"description":96,"link":97,"items":102},"Automation","CI/CD and automation to accelerate deployment",{"config":98},{"icon":99,"href":100,"dataGaName":101,"dataGaLocation":41},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[103,107,110,114],{"text":104,"config":105},"CI/CD",{"href":106,"dataGaLocation":41,"dataGaName":104},"/solutions/continuous-integration/",{"text":70,"config":108},{"href":75,"dataGaLocation":41,"dataGaName":109},"gitlab duo agent platform - product menu",{"text":111,"config":112},"Source Code Management",{"href":113,"dataGaLocation":41,"dataGaName":111},"/solutions/source-code-management/",{"text":115,"config":116},"Automated Software Delivery",{"href":100,"dataGaLocation":41,"dataGaName":117},"Automated software delivery",{"title":119,"description":120,"link":121,"items":126},"Security","Deliver code faster without compromising security",{"config":122},{"href":123,"dataGaName":124,"dataGaLocation":41,"icon":125},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[127,131,136],{"text":128,"config":129},"Application Security Testing",{"href":123,"dataGaName":130,"dataGaLocation":41},"Application security testing",{"text":132,"config":133},"Software Supply Chain Security",{"href":134,"dataGaLocation":41,"dataGaName":135},"/solutions/supply-chain/","Software supply chain security",{"text":137,"config":138},"Software Compliance",{"href":139,"dataGaName":140,"dataGaLocation":41},"/solutions/software-compliance/","software compliance",{"title":142,"link":143,"items":148},"Measurement",{"config":144},{"icon":145,"href":146,"dataGaName":147,"dataGaLocation":41},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[149,153,157],{"text":150,"config":151},"Visibility & Measurement",{"href":146,"dataGaLocation":41,"dataGaName":152},"Visibility and Measurement",{"text":154,"config":155},"Value Stream Management",{"href":156,"dataGaLocation":41,"dataGaName":154},"/solutions/value-stream-management/",{"text":158,"config":159},"Analytics & Insights",{"href":160,"dataGaLocation":41,"dataGaName":161},"/solutions/analytics-and-insights/","Analytics and insights",{"title":163,"items":164},"GitLab for",[165,170,175],{"text":166,"config":167},"Enterprise",{"href":168,"dataGaLocation":41,"dataGaName":169},"/enterprise/","enterprise",{"text":171,"config":172},"Small Business",{"href":173,"dataGaLocation":41,"dataGaName":174},"/small-business/","small business",{"text":176,"config":177},"Public Sector",{"href":178,"dataGaLocation":41,"dataGaName":179},"/solutions/public-sector/","public sector",{"text":181,"config":182},"Pricing",{"href":183,"dataGaName":184,"dataGaLocation":41,"dataNavLevelOne":184},"/pricing/","pricing",{"text":186,"config":187,"link":189,"lists":193,"feature":273},"Resources",{"dataNavLevelOne":188},"resources",{"text":190,"config":191},"View all resources",{"href":192,"dataGaName":188,"dataGaLocation":41},"/resources/",[194,227,245],{"title":195,"items":196},"Getting started",[197,202,207,212,217,222],{"text":198,"config":199},"Install",{"href":200,"dataGaName":201,"dataGaLocation":41},"/install/","install",{"text":203,"config":204},"Quick start guides",{"href":205,"dataGaName":206,"dataGaLocation":41},"/get-started/","quick setup checklists",{"text":208,"config":209},"Learn",{"href":210,"dataGaLocation":41,"dataGaName":211},"https://university.gitlab.com/","learn",{"text":213,"config":214},"Product documentation",{"href":215,"dataGaName":216,"dataGaLocation":41},"https://docs.gitlab.com/","product documentation",{"text":218,"config":219},"Best practice videos",{"href":220,"dataGaName":221,"dataGaLocation":41},"/getting-started-videos/","best practice videos",{"text":223,"config":224},"Integrations",{"href":225,"dataGaName":226,"dataGaLocation":41},"/integrations/","integrations",{"title":228,"items":229},"Discover",[230,235,240],{"text":231,"config":232},"Customer success stories",{"href":233,"dataGaName":234,"dataGaLocation":41},"/customers/","customer success stories",{"text":236,"config":237},"Blog",{"href":238,"dataGaName":239,"dataGaLocation":41},"/blog/","blog",{"text":241,"config":242},"Remote",{"href":243,"dataGaName":244,"dataGaLocation":41},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":246,"items":247},"Connect",[248,253,258,263,268],{"text":249,"config":250},"GitLab Services",{"href":251,"dataGaName":252,"dataGaLocation":41},"/services/","services",{"text":254,"config":255},"Community",{"href":256,"dataGaName":257,"dataGaLocation":41},"/community/","community",{"text":259,"config":260},"Forum",{"href":261,"dataGaName":262,"dataGaLocation":41},"https://forum.gitlab.com/","forum",{"text":264,"config":265},"Events",{"href":266,"dataGaName":267,"dataGaLocation":41},"/events/","events",{"text":269,"config":270},"Partners",{"href":271,"dataGaName":272,"dataGaLocation":41},"/partners/","partners",{"backgroundColor":274,"textColor":275,"text":276,"image":277,"link":281},"#2f2a6b","#fff","Insights for the future of software development",{"altText":278,"config":279},"the source promo card",{"src":280},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758208064/dzl0dbift9xdizyelkk4.svg",{"text":282,"config":283},"Read the latest",{"href":284,"dataGaName":285,"dataGaLocation":41},"/the-source/","the source",{"text":287,"config":288,"lists":290},"Company",{"dataNavLevelOne":289},"company",[291],{"items":292},[293,298,304,306,311,316,321,326,331,336,341],{"text":294,"config":295},"About",{"href":296,"dataGaName":297,"dataGaLocation":41},"/company/","about",{"text":299,"config":300,"footerGa":303},"Jobs",{"href":301,"dataGaName":302,"dataGaLocation":41},"/jobs/","jobs",{"dataGaName":302},{"text":264,"config":305},{"href":266,"dataGaName":267,"dataGaLocation":41},{"text":307,"config":308},"Leadership",{"href":309,"dataGaName":310,"dataGaLocation":41},"/company/team/e-group/","leadership",{"text":312,"config":313},"Team",{"href":314,"dataGaName":315,"dataGaLocation":41},"/company/team/","team",{"text":317,"config":318},"Handbook",{"href":319,"dataGaName":320,"dataGaLocation":41},"https://handbook.gitlab.com/","handbook",{"text":322,"config":323},"Investor relations",{"href":324,"dataGaName":325,"dataGaLocation":41},"https://ir.gitlab.com/","investor relations",{"text":327,"config":328},"Trust Center",{"href":329,"dataGaName":330,"dataGaLocation":41},"/security/","trust center",{"text":332,"config":333},"AI Transparency Center",{"href":334,"dataGaName":335,"dataGaLocation":41},"/ai-transparency-center/","ai transparency center",{"text":337,"config":338},"Newsletter",{"href":339,"dataGaName":340,"dataGaLocation":41},"/company/contact/#contact-forms","newsletter",{"text":342,"config":343},"Press",{"href":344,"dataGaName":345,"dataGaLocation":41},"/press/","press",{"text":347,"config":348,"lists":349},"Contact us",{"dataNavLevelOne":289},[350],{"items":351},[352,355,360],{"text":48,"config":353},{"href":50,"dataGaName":354,"dataGaLocation":41},"talk to sales",{"text":356,"config":357},"Support portal",{"href":358,"dataGaName":359,"dataGaLocation":41},"https://support.gitlab.com","support portal",{"text":361,"config":362},"Customer portal",{"href":363,"dataGaName":364,"dataGaLocation":41},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":366,"login":367,"suggestions":374},"Close",{"text":368,"link":369},"To search repositories and projects, login to",{"text":370,"config":371},"gitlab.com",{"href":55,"dataGaName":372,"dataGaLocation":373},"search login","search",{"text":375,"default":376},"Suggestions",[377,379,383,385,389,393],{"text":70,"config":378},{"href":75,"dataGaName":70,"dataGaLocation":373},{"text":380,"config":381},"Code Suggestions (AI)",{"href":382,"dataGaName":380,"dataGaLocation":373},"/solutions/code-suggestions/",{"text":104,"config":384},{"href":106,"dataGaName":104,"dataGaLocation":373},{"text":386,"config":387},"GitLab on AWS",{"href":388,"dataGaName":386,"dataGaLocation":373},"/partners/technology-partners/aws/",{"text":390,"config":391},"GitLab on Google Cloud",{"href":392,"dataGaName":390,"dataGaLocation":373},"/partners/technology-partners/google-cloud-platform/",{"text":394,"config":395},"Why GitLab?",{"href":83,"dataGaName":394,"dataGaLocation":373},{"freeTrial":397,"mobileIcon":402,"desktopIcon":407,"secondaryButton":410},{"text":398,"config":399},"Start free trial",{"href":400,"dataGaName":46,"dataGaLocation":401},"https://gitlab.com/-/trials/new/","nav",{"altText":403,"config":404},"Gitlab Icon",{"src":405,"dataGaName":406,"dataGaLocation":401},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":403,"config":408},{"src":409,"dataGaName":406,"dataGaLocation":401},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":411,"config":412},"Get Started",{"href":413,"dataGaName":414,"dataGaLocation":401},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/get-started/","get started",{"freeTrial":416,"mobileIcon":420,"desktopIcon":422},{"text":417,"config":418},"Learn more about GitLab Duo",{"href":75,"dataGaName":419,"dataGaLocation":401},"gitlab duo",{"altText":403,"config":421},{"src":405,"dataGaName":406,"dataGaLocation":401},{"altText":403,"config":423},{"src":409,"dataGaName":406,"dataGaLocation":401},{"button":425,"mobileIcon":430,"desktopIcon":432},{"text":426,"config":427},"/switch",{"href":428,"dataGaName":429,"dataGaLocation":401},"#contact","switch",{"altText":403,"config":431},{"src":405,"dataGaName":406,"dataGaLocation":401},{"altText":403,"config":433},{"src":434,"dataGaName":406,"dataGaLocation":401},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":436,"mobileIcon":441,"desktopIcon":443},{"text":437,"config":438},"Back to pricing",{"href":183,"dataGaName":439,"dataGaLocation":401,"icon":440},"back to pricing","GoBack",{"altText":403,"config":442},{"src":405,"dataGaName":406,"dataGaLocation":401},{"altText":403,"config":444},{"src":409,"dataGaName":406,"dataGaLocation":401},{"title":446,"button":447,"config":452},"See how agentic AI transforms software delivery",{"text":448,"config":449},"Watch GitLab Transcend now",{"href":450,"dataGaName":451,"dataGaLocation":41},"/events/transcend/virtual/","transcend event",{"layout":453,"icon":454,"disabled":11},"release","AiStar",{"data":456},{"text":457,"source":458,"edit":464,"contribute":469,"config":474,"items":479,"minimal":686},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":459,"config":460},"View page source",{"href":461,"dataGaName":462,"dataGaLocation":463},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":465,"config":466},"Edit this page",{"href":467,"dataGaName":468,"dataGaLocation":463},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":470,"config":471},"Please contribute",{"href":472,"dataGaName":473,"dataGaLocation":463},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":475,"facebook":476,"youtube":477,"linkedin":478},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[480,527,581,625,652],{"title":181,"links":481,"subMenu":496},[482,486,491],{"text":483,"config":484},"View plans",{"href":183,"dataGaName":485,"dataGaLocation":463},"view plans",{"text":487,"config":488},"Why Premium?",{"href":489,"dataGaName":490,"dataGaLocation":463},"/pricing/premium/","why premium",{"text":492,"config":493},"Why Ultimate?",{"href":494,"dataGaName":495,"dataGaLocation":463},"/pricing/ultimate/","why ultimate",[497],{"title":498,"links":499},"Contact Us",[500,503,505,507,512,517,522],{"text":501,"config":502},"Contact sales",{"href":50,"dataGaName":51,"dataGaLocation":463},{"text":356,"config":504},{"href":358,"dataGaName":359,"dataGaLocation":463},{"text":361,"config":506},{"href":363,"dataGaName":364,"dataGaLocation":463},{"text":508,"config":509},"Status",{"href":510,"dataGaName":511,"dataGaLocation":463},"https://status.gitlab.com/","status",{"text":513,"config":514},"Terms of use",{"href":515,"dataGaName":516,"dataGaLocation":463},"/terms/","terms of use",{"text":518,"config":519},"Privacy statement",{"href":520,"dataGaName":521,"dataGaLocation":463},"/privacy/","privacy statement",{"text":523,"config":524},"Cookie preferences",{"dataGaName":525,"dataGaLocation":463,"id":526,"isOneTrustButton":11},"cookie preferences","ot-sdk-btn",{"title":86,"links":528,"subMenu":537},[529,533],{"text":530,"config":531},"DevSecOps platform",{"href":68,"dataGaName":532,"dataGaLocation":463},"devsecops platform",{"text":534,"config":535},"AI-Assisted Development",{"href":75,"dataGaName":536,"dataGaLocation":463},"ai-assisted development",[538],{"title":539,"links":540},"Topics",[541,546,551,556,561,566,571,576],{"text":542,"config":543},"CICD",{"href":544,"dataGaName":545,"dataGaLocation":463},"/topics/ci-cd/","cicd",{"text":547,"config":548},"GitOps",{"href":549,"dataGaName":550,"dataGaLocation":463},"/topics/gitops/","gitops",{"text":552,"config":553},"DevOps",{"href":554,"dataGaName":555,"dataGaLocation":463},"/topics/devops/","devops",{"text":557,"config":558},"Version Control",{"href":559,"dataGaName":560,"dataGaLocation":463},"/topics/version-control/","version control",{"text":562,"config":563},"DevSecOps",{"href":564,"dataGaName":565,"dataGaLocation":463},"/topics/devsecops/","devsecops",{"text":567,"config":568},"Cloud Native",{"href":569,"dataGaName":570,"dataGaLocation":463},"/topics/cloud-native/","cloud native",{"text":572,"config":573},"AI for Coding",{"href":574,"dataGaName":575,"dataGaLocation":463},"/topics/devops/ai-for-coding/","ai for coding",{"text":577,"config":578},"Agentic AI",{"href":579,"dataGaName":580,"dataGaLocation":463},"/topics/agentic-ai/","agentic ai",{"title":582,"links":583},"Solutions",[584,586,588,593,597,600,604,607,609,612,615,620],{"text":128,"config":585},{"href":123,"dataGaName":128,"dataGaLocation":463},{"text":117,"config":587},{"href":100,"dataGaName":101,"dataGaLocation":463},{"text":589,"config":590},"Agile development",{"href":591,"dataGaName":592,"dataGaLocation":463},"/solutions/agile-delivery/","agile delivery",{"text":594,"config":595},"SCM",{"href":113,"dataGaName":596,"dataGaLocation":463},"source code management",{"text":542,"config":598},{"href":106,"dataGaName":599,"dataGaLocation":463},"continuous integration & delivery",{"text":601,"config":602},"Value stream management",{"href":156,"dataGaName":603,"dataGaLocation":463},"value stream management",{"text":547,"config":605},{"href":606,"dataGaName":550,"dataGaLocation":463},"/solutions/gitops/",{"text":166,"config":608},{"href":168,"dataGaName":169,"dataGaLocation":463},{"text":610,"config":611},"Small business",{"href":173,"dataGaName":174,"dataGaLocation":463},{"text":613,"config":614},"Public sector",{"href":178,"dataGaName":179,"dataGaLocation":463},{"text":616,"config":617},"Education",{"href":618,"dataGaName":619,"dataGaLocation":463},"/solutions/education/","education",{"text":621,"config":622},"Financial services",{"href":623,"dataGaName":624,"dataGaLocation":463},"/solutions/finance/","financial services",{"title":186,"links":626},[627,629,631,633,636,638,640,642,644,646,648,650],{"text":198,"config":628},{"href":200,"dataGaName":201,"dataGaLocation":463},{"text":203,"config":630},{"href":205,"dataGaName":206,"dataGaLocation":463},{"text":208,"config":632},{"href":210,"dataGaName":211,"dataGaLocation":463},{"text":213,"config":634},{"href":215,"dataGaName":635,"dataGaLocation":463},"docs",{"text":236,"config":637},{"href":238,"dataGaName":239,"dataGaLocation":463},{"text":231,"config":639},{"href":233,"dataGaName":234,"dataGaLocation":463},{"text":241,"config":641},{"href":243,"dataGaName":244,"dataGaLocation":463},{"text":249,"config":643},{"href":251,"dataGaName":252,"dataGaLocation":463},{"text":254,"config":645},{"href":256,"dataGaName":257,"dataGaLocation":463},{"text":259,"config":647},{"href":261,"dataGaName":262,"dataGaLocation":463},{"text":264,"config":649},{"href":266,"dataGaName":267,"dataGaLocation":463},{"text":269,"config":651},{"href":271,"dataGaName":272,"dataGaLocation":463},{"title":287,"links":653},[654,656,658,660,662,664,666,670,675,677,679,681],{"text":294,"config":655},{"href":296,"dataGaName":289,"dataGaLocation":463},{"text":299,"config":657},{"href":301,"dataGaName":302,"dataGaLocation":463},{"text":307,"config":659},{"href":309,"dataGaName":310,"dataGaLocation":463},{"text":312,"config":661},{"href":314,"dataGaName":315,"dataGaLocation":463},{"text":317,"config":663},{"href":319,"dataGaName":320,"dataGaLocation":463},{"text":322,"config":665},{"href":324,"dataGaName":325,"dataGaLocation":463},{"text":667,"config":668},"Sustainability",{"href":669,"dataGaName":667,"dataGaLocation":463},"/sustainability/",{"text":671,"config":672},"Diversity, inclusion and belonging (DIB)",{"href":673,"dataGaName":674,"dataGaLocation":463},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":327,"config":676},{"href":329,"dataGaName":330,"dataGaLocation":463},{"text":337,"config":678},{"href":339,"dataGaName":340,"dataGaLocation":463},{"text":342,"config":680},{"href":344,"dataGaName":345,"dataGaLocation":463},{"text":682,"config":683},"Modern Slavery Transparency Statement",{"href":684,"dataGaName":685,"dataGaLocation":463},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":687},[688,691,694],{"text":689,"config":690},"Terms",{"href":515,"dataGaName":516,"dataGaLocation":463},{"text":692,"config":693},"Cookies",{"dataGaName":525,"dataGaLocation":463,"id":526,"isOneTrustButton":11},{"text":695,"config":696},"Privacy",{"href":520,"dataGaName":521,"dataGaLocation":463},[698],{"id":699,"title":21,"body":8,"config":700,"content":703,"description":8,"extension":26,"meta":707,"navigation":11,"path":708,"seo":709,"stem":710,"__hash__":711},"blogAuthors/en-us/blog/authors/omid-khan.yml",{"template":701,"gitlabHandle":702},"BlogAuthor","OmidKhan",{"name":21,"config":704,"role":706},{"headshot":705},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1769090536/q4p3qwthtken8fpokgzu.jpg","",{},"/en-us/blog/authors/omid-khan",{},"en-us/blog/authors/omid-khan","4ZHOi5nEiZLdJm1phW-47SM0x-BGo8jNbg_Zt0oSzEQ",[713,726,739],{"content":714,"config":724},{"title":715,"description":716,"authors":717,"date":719,"body":720,"category":9,"tags":721,"heroImage":723},"Prepare your pipeline for AI-discovered zero-days","AI is finding vulnerabilities faster than teams can patch. Learn how pipeline enforcement, automated triage, and AI remediation close the gap.",[718],"Omer Azaria","2026-04-20","Anthropic's [Mythos Preview model](https://red.anthropic.com/2026/mythos-preview/) recently identified thousands of zero-day vulnerabilities across every major operating system and web browser, including an OpenBSD bug that went undetected for 27 years. In testing, Mythos autonomously chained four vulnerabilities into a working browser exploit that escaped its sandbox. Anthropic is restricting access to Mythos, but the company’s head of offensive cyber research expects threats to have comparable tooling within six to twelve months.\n\nThe defender side of the equation hasn't kept pace. One third of exploited Common Vulnerabilities and Exposures (CVEs) in the first half of 2025 showed activity on or before disclosure day, before most teams even know there's something to patch. AI is compressing that window further, accelerating attackers and flooding teams with whitehat disclosures faster than they can triage. Defender tooling has improved, but most organizations can't operationalize it fast enough to close the gap between discovery and exploitation.\n\nWhen the window between disclosure and exploitation is measured in hours, the security team can't be the last line of defense. Security has to run where code enters the system: in the pipeline, on every merge request, enforced by policy. The fixes that can be automated should be. The ones that can't need to reach the right human faster than they do today.\n\n## Known vulnerabilities are already outpacing remediation\n\nThe bottleneck isn't detection, it's acting at scale on what teams already know. Sixty percent of breaches in the 2025 Verizon DBIR involved exploiting known vulnerabilities where a patch was already available. Teams couldn’t close them in time.\n\nThe backlog was untenable before Mythos. Developers spend [11 hours per month remediating vulnerabilities](https://about.gitlab.com/resources/developer-survey/) post-release instead of shipping new work. Over half of organizations have at least one open internet-facing vulnerability, and the median time to close half of those is 361 days. Exploitation takes hours, while remediation takes months.\n\nAI-assisted development is widening the gap, and stakeholders know it. By June 2025, AI-generated code was adding over 10,000 new security findings per month across Fortune 50 repositories, a 10x jump from six months earlier. Georgia Tech identified 34 [CVEs attributable to AI-generated code](https://research.gatech.edu/bad-vibes-ai-generated-code-vulnerable-researchers-warn) in March 2026, up from 6 in January, and that count reflects only the ones where AI authorship is clear. AI coding assistants hallucinate package names, reach for outdated patterns, and copy insecure examples from training data. More code, more dependencies, and more vulnerabilities per line are generated faster than security teams can review them.\n\nDefenders need to harness frontier AI models, too — not bolted onto the SDLC as external tooling, but running inside the same policies, approvals, and audit trail as the rest of the team. \n\n## Security at the speed of AI coding\n\nWhen a critical CVE drops, how quickly can your team confirm which projects are affected? How many tools does an alert cross before a developer can submit a fix?\n\nThe teams that benefit most from AI already have policies, enforcement, and controls embedded in their development workflows. AI amplifies that foundation. It doesn't replace it.\n\n**Enforcement at the point of change.** As exploitation windows compress, every line of code entering a repository needs to pass through a defined set of controls. Not a separate review, in a different tool, by a different team. Organizations need the ability to enforce security policies across every group and project, with the merge request as the enforcement point. Policies defined once, applied everywhere, with exceptions reviewed, approved, and logged.\n\n**Simple issues caught before the merge request, not during.** Hardcoded secrets, known-vulnerable imports, and deprecated API calls can be flagged in the IDE before a developer pushes a commit. Catching them at authoring time means fewer findings blocking the MR, so review cycles go to the findings that require cross-component context: reachability, exploitability, and architectural risk.\n\n**Triage automated by default, not by exception.** Embedding security into every merge request creates a volume problem. More scans, more findings, more noise reaching developers who aren’t trained to distinguish a reachable critical from a theoretical one. AI must handle false positive detection, reachability, exploitability context, and severity assessment before a developer sees the finding, so the findings they see actually warrant their time.\n\n**Remediation governed like any other change.** AI-based remediation compresses the timeline for closing vulnerabilities, but every generated fix must move through the same governance as a human-authored change: policies enforce scans, the right reviewers approve, and evidence is recorded. GitLab’s automated remediation capability proposes each fix in a merge request with a confidence score. The MR records which policy applied, which scans ran, what they found, and who approved. Human code and AI-generated code move through the same process, with the same audit trail.\n\n## What a ready pipeline looks like\n\nHere's how these pieces work together when a high-severity vulnerability is discovered and the clock is running.\n\nA proof-of-concept exploit for a vulnerability in a popular open-source package appears on a security mailing list. There’s no CVE, no National Vulnerability Database (NVD) entry, and no scanner signature yet. The security team finds out the usual way: someone shares it in Slack.\n\nA security engineer asks the security agent if the package is in use, which projects have affected versions, and whether any vulnerable call paths are reachable in production. The agent checks the dependency graph for every project, matches the affected versions and entry points from the disclosure, and returns a ranked list of exposed projects with details about reachability. There’s no need to search through repositories by hand or wait for a scanner update. The question, \"Are we exposed?\" is answered in minutes.\n\nThe engineer starts a remediation campaign for every exposed project. The remediation agent suggests fixes: version updates where a patched release is available, and targeted call-path patches where it is not. Scan execution policies are already in place for projects tagged SOC 2. The engineer hardens the rules to block merges on any merge request that introduces or keeps the affected dependency, and an approval policy now requires security sign-off on every fix. The agent's first proposed patch fails the pipeline when an integration test catches a regression. The agent revises the patch based on the test failure, and the second attempt passes. Developers review the changes, security signs off under the stricter policy, and merges proceed across the campaign.\n\nAt the next audit review, the security team presents a report showing how policies were enforced and risks were reduced during the campaign. It includes scan results, policies applied, approvers, and merge timestamps for every MR in every affected project. The evidence was automatically generated in flight, not assembled after the fact.\n\n## Close the gaps now\n\nMythos exists today, and comparable models will be in attacker hands within a year. Every month between now and then is a chance to strengthen your software supply chain.\n\nAsk these questions about your pipeline:\n\n* How do you enforce that security scans run on every merge request, not just the projects where teams configured them?\n\n* If a compromised package entered your dependency tree today, would your pipeline catch it before build?\n\n* When a scanner flags a critical finding, how many tool boundaries does it cross before a developer starts the fix?\n\n* If an AI agent proposed a code fix for a vulnerability, what process would that fix go through before reaching production, and is that process auditable?\n\n* When auditors ask for evidence that a specific policy was enforced on a specific change, how long does it take to produce?\n\nIf the answers expose gaps, address them now. [Talk to a GitLab solutions architect](https://about.gitlab.com/sales/) about the role of security governance in your development lifecycle.",[722,9,530],"AI/ML","https://res.cloudinary.com/about-gitlab-com/image/upload/v1772195014/ooezwusxjl1f7ijfmbvj.png",{"featured":11,"template":12,"slug":725},"prepare-your-pipeline-for-ai-discovered-zero-days",{"content":727,"config":737},{"title":728,"description":729,"authors":730,"heroImage":732,"date":733,"category":9,"tags":734,"body":736},"Manage vulnerability noise at scale with auto-dismiss policies","Learn how to cut through scanner noise and focus on the vulnerabilities that matter most with GitLab security, including use cases and templates.",[731],"Grant Hickman","https://res.cloudinary.com/about-gitlab-com/image/upload/v1774375772/kpaaaiqhokevxxeoxvu0.png","2026-03-25",[9,23,562,735,24],"features","Security scanners are essential, but not every finding requires action. Test code, vendored dependencies, generated files, and known false positives create noise that buries the vulnerabilities that actually matter. Security teams waste hours manually dismissing the same irrelevant findings across projects and pipelines. They experience slower triage, alert fatigue, and developer friction that undermines adoption of security scanning itself.\n\nGitLab's auto-dismiss vulnerability policies let you codify your triage decisions once and apply them automatically on every default-branch pipeline. Define criteria based on file path, directory, or vulnerability identifier (CVE, CWE), choose a dismissal reason, and let GitLab handle the rest.\n\n## Why auto-dismiss?\nAuto-dismiss vulnerability policies enable security teams to:\n- **Eliminate triage noise**: Automatically dismiss findings in test code, vendored dependencies, and generated files.\n- **Enforce decisions at scale**: Apply policies centrally to dismiss known false positives across your entire organization.\n- **Maintain audit transparency**: Every auto-dismissed finding includes a documented reason and links back to the policy that triggered it.\n- **Preserve the record**: Unlike scanner exclusions, dismissed vulnerabilities remain in your report, so you can revisit decisions if conditions change.\n\n## How auto-dismiss policies work\n\n1. **Define your policy** in a vulnerability management policy YAML file. Specify match criteria (file path, directory, or identifier) and a dismissal reason.\n\n2. **Merge and activate.** Create the policy via **Secure > Policies > New  policy > Vulnerability management policy**. Merge the MR to enable it.\n3. **Run your pipeline.** On every default-branch pipeline, matching vulnerabilities are automatically set to \"Dismissed\" with the specified reason. Up to 1,000 vulnerabilities are processed per run.\n4. **Measure the impact.** Filter your vulnerability report by status \"Dismissed\" to see exactly what was cleaned up and validate that the right findings are being handled.\n\n## Use cases with ready-to-use configurations\n\nEach example below includes a policy configuration you can copy, customize, and apply immediately.\n\n### 1. Dismiss test code vulnerabilities\n\nSAST and dependency scanners flag hardcoded credentials, insecure fixtures, and dev-only dependencies in test directories. These are not production risks.\n\n```yaml\nvulnerability_management_policy:\n  - name: \"Dismiss test code vulnerabilities\"\n    description: \"Auto-dismiss findings in test directories\"\n    enabled: true\n    rules:\n      - type: detected\n        criteria:\n          - type: file_path\n            value: \"test/**/*\"\n      - type: detected\n        criteria:\n          - type: file_path\n            value: \"tests/**/*\"\n      - type: detected\n        criteria:\n          - type: file_path\n            value: \"spec/**/*\"\n      - type: detected\n        criteria:\n          - type: directory\n            value: \"__tests__/*\"\n    actions:\n      - type: auto_dismiss\n        dismissal_reason: used_in_tests\n\n```\n\n### 2. Dismiss vendored and third-party code\n\nVulnerabilities in `vendor/`, `third_party/`, or checked-in `node_modules` are managed upstream and not actionable for your team.\n\n```yaml\nvulnerability_management_policy:\n  - name: \"Dismiss vendored dependency findings\"\n    description: \"Findings in vendored code are managed upstream\"\n    enabled: true\n    rules:\n      - type: detected\n        criteria:\n          - type: directory\n            value: \"vendor/*\"\n      - type: detected\n        criteria:\n          - type: directory\n            value: \"third_party/*\"\n      - type: detected\n        criteria:\n          - type: directory\n            value: \"vendored/*\"\n    actions:\n      - type: auto_dismiss\n        dismissal_reason: not_applicable\n\n```\n\n### 3. Dismiss known false positive CVEs\n\nCertain CVEs are repeatedly flagged but don't apply to your usage context. Teams dismiss these manually every time they appear. Replace the example CVEs below with your own.\n\n```yaml\nvulnerability_management_policy:\n  - name: \"Dismiss known false positive CVEs\"\n    description: \"CVEs confirmed as false positives for our environment\"\n    enabled: true\n    rules:\n      - type: detected\n        criteria:\n          - type: identifier\n            value: \"CVE-2023-44487\"\n      - type: detected\n        criteria:\n          - type: identifier\n            value: \"CVE-2024-29041\"\n      - type: detected\n        criteria:\n          - type: identifier\n            value: \"CVE-2023-26136\"\n    actions:\n      - type: auto_dismiss\n        dismissal_reason: false_positive\n\n```\n\n### 4. Dismiss generated and auto-created code\n\nProtobuf, gRPC, OpenAPI generators, and ORM scaffolding tools produce files with flagged patterns that cannot be patched by your team.\n\n```yaml\nvulnerability_management_policy:\n  - name: \"Dismiss generated code findings\"\n    description: \"Generated files are not authored by us\"\n    enabled: true\n    rules:\n      - type: detected\n        criteria:\n          - type: directory\n            value: \"generated/*\"\n      - type: detected\n        criteria:\n          - type: file_path\n            value: \"**/*.pb.go\"\n      - type: detected\n        criteria:\n          - type: file_path\n            value: \"**/*.generated.*\"\n    actions:\n      - type: auto_dismiss\n        dismissal_reason: not_applicable\n\n```\n\n### 5. Dismiss infrastructure-mitigated vulnerabilities\n\nVulnerability classes like XSS (CWE-79) or SQL injection (CWE-89) that are already addressed by WAF rules or runtime protection. Only use this when mitigating controls are verified and consistently enforced.\n\n```yaml\nvulnerability_management_policy:\n  - name: \"Dismiss CWEs mitigated by WAF\"\n    description: \"XSS and SQLi mitigated by WAF rules\"\n    enabled: true\n    rules:\n      - type: detected\n        criteria:\n          - type: identifier\n            value: \"CWE-79\"\n      - type: detected\n        criteria:\n          - type: identifier\n            value: \"CWE-89\"\n    actions:\n      - type: auto_dismiss\n        dismissal_reason: mitigating_control\n\n```\n\n### 6. Dismiss CVE families across your organization\n\nA wave of related CVEs for a widely-used library your team has assessed? Apply at the group level to dismiss them across dozens of projects. The wildcard pattern (e.g., `CVE-2021-44*`) matches all CVEs with that prefix.\n\n```yaml\nvulnerability_management_policy:\n  - name: \"Accept risk for log4j CVE family\"\n    description: \"Log4j CVEs mitigated by version pinning and WAF\"\n    enabled: true\n    rules:\n      - type: detected\n        criteria:\n          - type: identifier\n            value: \"CVE-2021-44*\"\n    actions:\n      - type: auto_dismiss\n        dismissal_reason: acceptable_risk\n\n```\n\n## Quick reference\n\n| Parameter | Details |\n|-----------|---------|\n| **Criteria types** | `file_path` (glob patterns, e.g., `test/**/*`), `directory` (e.g., `vendor/*`), `identifier` (CVE/CWE with wildcards, e.g., `CVE-2023-*`) |\n| **Dismissal reasons** | `acceptable_risk`, `false_positive`, `mitigating_control`, `used_in_tests`, `not_applicable` |\n| **Criteria logic** | Multiple criteria within a rule = AND (must match all). Multiple rules within a policy = OR (match any). |\n| **Limits** | 3 criteria per rule, 5 rules per policy, 5 policies per security policy project. Vulnerabilty management policy actions process 1000 vulnerabilities per pipeline run in the target project, until all matching vulnerabilities are processed. |\n| **Affected statuses** | Needs triage, Confirmed |\n| **Scope** | Project-level or group-level (group-level applies across all projects) |\n\n## Getting started\nHere's how to get started with auto-dismiss policies:\n\n1. **Identify the noise.** Open your vulnerability report and sort by \"Needs triage.\" Look for patterns: test files, vendored code, the same CVE across projects.\n\n2. **Pick a scenario.** Start with whichever use case above accounts for the most findings.\n\n3. **Record your baseline.** Note the number of \"Needs triage\" vulnerabilities before creating a policy.\n\n4. **Create and enable.** Navigate to **Secure > Policies > New policy > Vulnerability management policy**. Paste the configuration from the use case above, then merge the MR.\n\n5. **Validate results.** After the next default-branch pipeline, filter by status \"Dismissed\" to confirm the right findings were handled.\n\nFor full configuration details, see the [vulnerability management policy documentation](https://docs.gitlab.com/user/application_security/policies/vulnerability_management_policy/#auto-dismiss-policies).\n\n> Ready to take control of vulnerability noise? [Start a free GitLab Ultimate trial](https://about.gitlab.com/free-trial/) and configure your first auto-dismiss policy today.\n",{"slug":738,"featured":11,"template":12},"auto-dismiss-vulnerability-management-policy",{"content":740,"config":749},{"title":741,"description":742,"authors":743,"heroImage":745,"date":746,"body":747,"category":9,"tags":748},"GitLab 18.10 brings AI-native triage and remediation ","Learn about GitLab Duo Agent Platform capabilities that cut noise, surface real vulnerabilities, and turn findings into proposed fixes.",[744],"Alisa Ho","https://res.cloudinary.com/about-gitlab-com/image/upload/v1773843921/rm35fx4gylrsu9alf2fx.png","2026-03-19","GitLab 18.10 introduces new AI-powered security capabilities focused on improving the quality and speed of vulnerability management. Together, these features can help reduce the time developers spend investigating false positives and bring automated remediation directly into their workflow, so they can fix vulnerabilities without needing to be security experts.\n\nHere is what’s new:\n\n* [**Static Application Security Testing (SAST) false positive detection**](https://docs.gitlab.com/user/application_security/vulnerabilities/false_positive_detection/) **is now generally available.** This flow uses an LLM for agentic reasoning to determine the likelihood that a vulnerability is a false positive or not, so security and development teams can focus on remediating critical vulnerabilities first.  \n* [**Agentic SAST vulnerability resolution**](https://docs.gitlab.com/user/application_security/vulnerabilities/agentic_vulnerability_resolution/) **is now in beta.** Agentic SAST vulnerability resolution automatically creates a merge request with a proposed fix for verified SAST vulnerabilities, which can shorten time to remediation and reduce the need for deep security expertise.  \n* [**Secret false positive detection**](https://docs.gitlab.com/user/application_security/vulnerabilities/secret_false_positive_detection/) **is now in beta.** This flow brings the same AI-powered noise reduction to secret detection, flagging dummy and test secrets to save review effort.\n\nThese flows are available to GitLab Ultimate customers using GitLab Duo Agent Platform. \n\n## Cut triage time with SAST false positive detection\n\nTraditional SAST scanners flag every suspicious code pattern they find, regardless of whether code paths are reachable or frameworks already handle the risk. Without runtime context, they cannot distinguish a real vulnerability from safe code that just looks dangerous.\n\nThis means developers could spend hours investigating findings that turn out to be false positives. Over time, that can erode confidence in the report and slow down the teams responsible for fixing real risks.\n\nAfter each SAST scan, GitLab Duo Agent Platform automatically analyzes new critical and high severity findings and attaches:\n\n* A confidence score indicating how likely the finding is to be a false positive  \n* An AI-generated explanation describing the reasoning  \n* A visual badge that makes “Likely false positive” versus “Likely real” easy to scan in the UI\n\nThese findings appear in the [Vulnerability Report](https://docs.gitlab.com/user/application_security/vulnerability_report/), as shown below. You can filter the report to focus on findings marked as “Not false positive” so teams can spend their time addressing real vulnerabilities instead of sifting through noise.\n\n![Vulnerability report](https://res.cloudinary.com/about-gitlab-com/image/upload/v1773844787/i0eod01p7gawflllkgsr.png)\n\n\nGitLab Duo Agent Platform's assessment is a recommendation. You stay in control of every false positive to determine if it is valid, and you can audit the agent's reasoning at any time to build confidence in the model. \n\n\n## Turn vulnerabilities into automated fixes\n\nKnowing that a vulnerability is real is only half the work.  Remediation still requires understanding the code path, writing a safe patch, and making sure nothing else breaks.\n\nIf the vulnerability is identified as likely not be a false positive by the SAST false positive detection flow, the Agentic SAST vulnerability resolution flow automatically:\n\n1. Reads the vulnerable code and surrounding context from your repository  \n2. Generates high-quality proposed fixes  \n3. Validates fixes through automated testing   \n4. Opens a merge request with a proposed fix that includes:  \n   * Concrete code changes  \n   * A confidence score  \n   * An explanation of what changed and why\n\nIn this demo, you’ll see how GitLab can automatically take a SAST vulnerability all the way from detection to a ready-to-review merge request. Watch how the agent reads the code, generates and validates a fix, and opens an MR with clear, explainable changes so developers can remediate faster without being security experts.\n\n\u003Ciframe src=\"https://player.vimeo.com/video/1174573325?badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479\" frameborder=\"0\" allow=\"autoplay; fullscreen; picture-in-picture; clipboard-write; encrypted-media; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" style=\"position:absolute;top:0;left:0;width:100%;height:100%;\" title=\"GitLab 18.10 AI SAST False Positive Auto Remediation\">\u003C/iframe>\u003Cscript src=\"https://player.vimeo.com/api/player.js\">\u003C/script>\n\nAs with any AI-generated suggestion, you should review the proposed merge request carefully before merging.\n\n## Surface real secrets\n\nSecret detection is only useful if teams trust the results. When reports are full of test credentials, placeholder values, and example tokens, developers may waste time reviewing noise instead of fixing real exposures. That can slow remediation and decrease confidence in the scan.\n\nSecret false positive detection helps teams focus on the secrets that matter so they can reduce risk faster. When it runs on the default branch, it will automatically:\n\n1. Analyze each finding to spot likely test credentials, example values, and dummy secrets  \n2. Assign a confidence score for whether the finding is a real risk or a likely false positive  \n3. Generate an explanation for why the secret is being treated as real or noise  \n4. Add a badge in the Vulnerability Report so developers can see the status at a glance\n\nDevelopers can also trigger this analysis manually from the Vulnerability Report by selecting **“Check for false positive”** on any secret detection finding, helping them clear out findings that do not pose risk and focus on real secrets sooner.\n\n## Try AI-powered security today\n\nGitLab 18.10 introduces capabilities that cover the full vulnerability workflow, from cutting false positive noise in SAST and secret detection to automatically generating merge requests with proposed fixes.\n\nTo see how AI-powered security can help cut review time and turn findings into ready-to-merge fixes, [start a free trial of GitLab Duo Agent Platform today](https://about.gitlab.com/gitlab-duo-agent-platform/?utm_medium=blog&utm_source=blog&utm_campaign=eg_global_x_x_security_en_).",[24,9,735],{"featured":31,"template":12,"slug":750},"gitlab-18-10-brings-ai-native-triage-and-remediation",{"promotions":752},[753,767,778,789],{"id":754,"categories":755,"header":757,"text":758,"button":759,"image":764},"ai-modernization",[756],"ai-ml","Is AI achieving its promise at scale?","Quiz will take 5 minutes or less",{"text":760,"config":761},"Get your AI maturity score",{"href":762,"dataGaName":763,"dataGaLocation":239},"/assessments/ai-modernization-assessment/","modernization assessment",{"config":765},{"src":766},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":768,"categories":769,"header":770,"text":758,"button":771,"image":775},"devops-modernization",[24,565],"Are you just managing tools or shipping innovation?",{"text":772,"config":773},"Get your DevOps maturity score",{"href":774,"dataGaName":763,"dataGaLocation":239},"/assessments/devops-modernization-assessment/",{"config":776},{"src":777},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":779,"categories":780,"header":781,"text":758,"button":782,"image":786},"security-modernization",[9],"Are you trading speed for security?",{"text":783,"config":784},"Get your security maturity score",{"href":785,"dataGaName":763,"dataGaLocation":239},"/assessments/security-modernization-assessment/",{"config":787},{"src":788},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":790,"paths":791,"header":794,"text":795,"button":796,"image":801},"github-azure-migration",[792,793],"migration-from-azure-devops-to-gitlab","integrating-azure-devops-scm-and-gitlab","Is your team ready for GitHub's Azure move?","GitHub is already rebuilding around Azure. Find out what it means for you.",{"text":797,"config":798},"See how GitLab compares to GitHub",{"href":799,"dataGaName":800,"dataGaLocation":239},"/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":802},{"src":777},{"header":804,"blurb":805,"button":806,"secondaryButton":811},"Start building faster today","See what your team can do with the intelligent orchestration platform for DevSecOps.\n",{"text":807,"config":808},"Get your free trial",{"href":809,"dataGaName":46,"dataGaLocation":810},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":501,"config":812},{"href":50,"dataGaName":51,"dataGaLocation":810},1777302600405]