GE-Enforce Collector API Key Fix

Issue Date: Identified September 14, 2026

Last Check-in: August 28, 2026 at 9:55 PM

Affected Systems: All GE-Enforce client machines

CRITICAL: GE-Enforce profiles stopped checking in on August 28, 2026. Collector API token was likely revoked. Immediate action required to restore service.

Table of Contents

1. Problem Summary

What Happened

On August 28, 2026, a major code deployment introduced a new collector authentication system that supports per-plugin managed tokens. As part of this change:

Technical Details

Code Change: Commit 80bb7b5ba1 - "Merge wilm: endpoints plugin, agent, policies"

Affected File: shopdb/core/api/collector.py

Before August 28:
if api_key == expected_key:
    return None  # Authorized
After August 28:
if expected_key and api_key == expected_key \
        and not _env_fallback_disabled(pluginname):  # NEW CHECK
    return None  # Authorized

2. Diagnosis

Check Production Database

-- Check if .env fallback is disabled
SELECT * FROM settings
WHERE key = 'plugin.geenforce.envkeyfallback';

-- Expected result if disabled: value = 'false'
-- Expected result if enabled: no rows or value = 'true'

-- Check last check-in
SELECT MAX(receivedat) as last_checkin,
       COUNT(DISTINCT hostname) as unique_hosts
FROM manifestenforcementreports
WHERE iscurrent = 1;

-- Check managed tokens
SELECT * FROM apitokens
WHERE scope LIKE '%geenforce%'
ORDER BY createdat DESC;

Check IIS Logs

Look for collector requests failing:

POST /api/collector/geenforce
Status: 401 Unauthorized
Error: "Invalid API key" or "Token revoked"

3. Quick Fix (Database)

Emergency Fix: Re-enable .env API key fallback to restore service immediately.
1 Connect to production database
2 Re-enable .env fallback
-- Option A: Delete the setting (defaults to enabled)
DELETE FROM settings
WHERE key = 'plugin.geenforce.envkeyfallback';

-- Option B: Explicitly set to true
INSERT INTO settings (key, value, valuetype)
VALUES ('plugin.geenforce.envkeyfallback', 'true', 'boolean')
ON DUPLICATE KEY UPDATE value = 'true';
3 Verify clients start checking in
-- Wait 15-30 minutes, then check
SELECT MAX(receivedat) as last_checkin
FROM manifestenforcementreports
WHERE receivedat > NOW() - INTERVAL 1 HOUR;
Note: This assumes your .env file has a valid COLLECTOR_API_KEY and all GE-Enforce clients are configured with that key.

4. Intune DSC Deployment

Deploy the API key to all GE-Enforce client machines via Intune.

GE-Enforce Registry Configuration

Registry Path Value Name Value Type Purpose
HKLM:\SOFTWARE\GE\ShopDB BaseUrl REG_SZ ShopDB server URL
HKLM:\SOFTWARE\GE\ShopDB ApiToken REG_SZ Collector API key

Option 1: PowerShell Script RECOMMENDED

Deployment Path: Intune Portal > Devices > Scripts > Add Windows 10 script

1 Create PowerShell script

Save as Deploy-GEEnforceAPIKey.ps1:

<#
.SYNOPSIS
    Deploy GE-Enforce collector API key via Intune

.DESCRIPTION
    Writes the ShopDB API token to registry for GE-Enforce client.
    Run as SYSTEM, no user context needed.

.NOTES
    Deploy via: Intune > Devices > Scripts > Add
    Run as: SYSTEM
    Platform: Windows 10/11
#>

$ErrorActionPreference = 'Stop'

# ============================================
# CONFIGURATION - UPDATE THESE VALUES
# ============================================
$ShopdbBaseUrl = "https://shopdb.your-company.com"
$ShopdbApiToken = "shopdb_pat_YOUR_NEW_TOKEN_HERE"  # Replace with actual token

# ============================================
# REGISTRY CONFIGURATION
# ============================================
$RegPath = 'HKLM:\SOFTWARE\GE\ShopDB'

try {
    Write-Output "Starting GE-Enforce API key deployment..."

    # Create registry key if it doesn't exist
    if (-not (Test-Path $RegPath)) {
        New-Item -Path $RegPath -Force | Out-Null
        Write-Output "Created registry path: $RegPath"
    }

    # Set BaseUrl
    Set-ItemProperty -Path $RegPath -Name 'BaseUrl' -Value $ShopdbBaseUrl -Type String
    Write-Output "Set BaseUrl: $ShopdbBaseUrl"

    # Set ApiToken (REG_SZ - plain text). HKLM\SOFTWARE\GE\ShopDB inherits
    # read for BUILTIN\Users, so any logged-on user can read this value unless
    # an ACL is applied to the key. Per-PC credentials remove the need for a
    # fleet secret here: see plugins/endpoints/docs/PER-PC-CREDENTIALS-ROLLOUT.md
    Set-ItemProperty -Path $RegPath -Name 'ApiToken' -Value $ShopdbApiToken -Type String

    # Verify token was written
    $savedToken = Get-ItemProperty -Path $RegPath -Name 'ApiToken' -ErrorAction Stop
    if ($savedToken.ApiToken -eq $ShopdbApiToken) {
        Write-Output "Set ApiToken: [REDACTED - first 20 chars: $($ShopdbApiToken.Substring(0, 20))...]"
        Write-Output "SUCCESS: GE-Enforce API configuration deployed"
        exit 0
    } else {
        throw "Token verification failed"
    }

} catch {
    Write-Error "FAILED: $_"
    Write-Output "Registry path: $RegPath"
    Write-Output "Error details: $($_.Exception.Message)"
    exit 1
}
2 Configure Intune deployment
3 Assign to devices

Option 2: Configuration Profile ENTERPRISE

Deployment Path: Intune Portal > Devices > Configuration profiles > Create > Settings catalog

1 Create Settings Catalog profile
2 Add Settings

Setting 1: BaseUrl

Setting 2: ApiToken

3 Assign and deploy

Option 3: Full DSC Configuration ADVANCED

For Azure Automation DSC environments:

Configuration GEEnforceCollector {
    param(
        [Parameter(Mandatory)]
        [string]$BaseUrl,

        [Parameter(Mandatory)]
        [string]$ApiToken
    )

    Import-DscResource -ModuleName 'PSDesiredStateConfiguration'

    Node 'localhost' {

        Registry ShopDBBaseUrl {
            Key       = 'HKLM:\SOFTWARE\GE\ShopDB'
            ValueName = 'BaseUrl'
            ValueData = $BaseUrl
            ValueType = 'String'
            Ensure    = 'Present'
        }

        Registry ShopDBApiToken {
            Key       = 'HKLM:\SOFTWARE\GE\ShopDB'
            ValueName = 'ApiToken'
            ValueData = $ApiToken
            ValueType = 'String'
            Ensure    = 'Present'
            DependsOn = '[Registry]ShopDBBaseUrl'
        }

        Script VerifyGEEnforce {
            GetScript  = { @{ Result = Test-Path 'HKLM:\SOFTWARE\GE\ShopDB' } }
            TestScript = {
                $token = Get-ItemProperty -Path 'HKLM:\SOFTWARE\GE\ShopDB' -Name 'ApiToken' -ErrorAction SilentlyContinue
                return ($null -ne $token)
            }
            SetScript  = { Write-Verbose "Registry already configured by dependencies" }
            DependsOn  = '[Registry]ShopDBApiToken'
        }
    }
}

# Compile configuration
GEEnforceCollector -BaseUrl "https://shopdb.your-company.com" `
                   -ApiToken "shopdb_pat_YOUR_TOKEN_HERE" `
                   -OutputPath "C:\DSC\GEEnforce"

# Upload to Azure Automation and assign to nodes

5. Generate New API Token

Option A: Use Existing .env Key QUICKEST

On your production IIS server, check .env file:

# Look for:
COLLECTOR_API_KEY=shopdb_pat_abc123def456...

# Or plugin-specific:
COLLECTOR_API_KEY_GEENFORCE=shopdb_pat_xyz789...

Use this token in your Intune deployment script.

Option B: Generate New Managed Token RECOMMENDED

1 Connect to production server
2 Generate token via Flask CLI
# SSH/RDP to IIS server
cd C:\path\to\shopdb-flask

# Generate new token
flask token create collector.geenforce "GE-Enforce Collector - Intune" `
  --scope "collector.ingest.geenforce" `
  --userid 1

# Output will be:
# Token created: shopdb_pat_abc123def456...
# Copy this token for Intune deployment
3 Verify token in database
SELECT tokenprefix, scope, description, isactive, createdat
FROM apitokens
WHERE scope LIKE '%geenforce%'
ORDER BY createdat DESC
LIMIT 1;

6. Testing

Manual Registry Test (Before Intune Deployment)

Test on a single pilot machine first:

# Run as Administrator on a test machine
Set-ItemProperty -Path 'HKLM:\SOFTWARE\GE\ShopDB' `
  -Name 'BaseUrl' -Value 'https://shopdb.your-company.com'

Set-ItemProperty -Path 'HKLM:\SOFTWARE\GE\ShopDB' `
  -Name 'ApiToken' -Value 'shopdb_pat_YOUR_TOKEN_HERE'

# Verify registry
Get-ItemProperty -Path 'HKLM:\SOFTWARE\GE\ShopDB'

# Run GE-Enforce manually to test
& "C:\Program Files\GE-Enforce\Invoke-ShopdbEnforce.ps1"

# Check for errors in output

Verify Check-in on Server

-- Wait 15-30 minutes after deployment, then check database
SELECT hostname, scopename, status, lastcheckin, receivedat
FROM manifestenforcementreports
WHERE receivedat > NOW() - INTERVAL 1 HOUR
ORDER BY receivedat DESC;

Intune Deployment Status

Monitor deployment in Intune portal:

7. Monitoring

Create Alert for Missing Check-ins

-- Run this query on a schedule (every 6 hours)
-- Alert if any results returned
SELECT
    'geenforce' as collector,
    MAX(receivedat) as last_checkin,
    TIMESTAMPDIFF(HOUR, MAX(receivedat), NOW()) as hours_since,
    COUNT(DISTINCT hostname) as total_hosts
FROM manifestenforcementreports
WHERE iscurrent = 1
HAVING hours_since > 24;

-- Expected: 0 rows (all clients checking in)
-- Alert if: > 24 hours since last check-in

Dashboard Query

-- GE-Enforce fleet health dashboard
SELECT
    DATE(receivedat) as report_date,
    COUNT(DISTINCT hostname) as unique_hosts,
    COUNT(*) as total_reports,
    SUM(CASE WHEN status = 'success' THEN 1 ELSE 0 END) as successful,
    SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed
FROM manifestenforcementreports
WHERE receivedat > NOW() - INTERVAL 7 DAY
GROUP BY DATE(receivedat)
ORDER BY report_date DESC;

8. Rollback Plan

If deployment fails: Follow these steps to restore service.

Step 1: Re-enable .env Fallback (Immediate)

DELETE FROM settings
WHERE key = 'plugin.geenforce.envkeyfallback';

Step 2: Deploy Old Token via Intune

Re-deploy the original API key from .env file using same Intune script.

Step 3: Verify Recovery

SELECT MAX(receivedat) as last_checkin
FROM manifestenforcementreports
WHERE receivedat > NOW() - INTERVAL 1 HOUR;

Step 4: Review Logs

Check Intune device output logs for errors:

Summary Checklist

Step Action Owner Status
1 Verify problem in production database Admin ☐
2 Re-enable .env fallback (emergency fix) Admin ☐
3 Generate new API token (or get from .env) Admin ☐
4 Test manually on 1 pilot machine Engineer ☐
5 Create Intune PowerShell script Engineer ☐
6 Deploy to pilot group (5-10 machines) Admin ☐
7 Verify pilot check-ins in database Engineer ☐
8 Deploy to all GE-Enforce clients Admin ☐
9 Monitor check-ins for 24 hours Engineer ☐
10 Create monitoring alert Engineer ☐
Success Criteria: All GE-Enforce clients checking in within 1 hour of deployment, no 401 errors in IIS logs, monitoring alert configured.

Document Version: 1.0
Created: September 14, 2026
Repository: flask-shopdb/.github/
Related Changes: Commit 80bb7b5ba1 (August 28, 2026)