connectors

Set up the Active Directory connector

The Active Directory connector is a small Windows service that runs on your network, reads identity data from AD on Ploy's behalf, and optionally writes group membership changes back. AD credentials never leave your network; all connections are initiated outbound from the connector to https://api.joinploy.com.

What you need before you start

  • A domain-joined Windows Server 2019 or later to host the connector service.

  • PowerShell 5.1+ running as Administrator on the connector host.

  • The RSAT AD PowerShell module on the host where you will create the gMSA (typically a domain controller):

    Install-WindowsFeature RSAT-AD-PowerShell
  • Outbound HTTPS (port 443) from the connector host to api.joinploy.com.

  • A bearer key from the Ploy admin UI. It must start with ploy_ct_.

Download the connector

  1. Download ploy-connector-<version>-windows-amd64.zip from the Ploy console.

  2. Extract it to C:\Program Files\Ploy\Connector\. The folder contains:

    • ploy-connector.exe

    • config.example.yaml

    • INSTALL.txt

Provision a Group Managed Service Account

A gMSA is an AD-managed identity whose password rotates automatically and never needs to be stored. The connector authenticates to AD as this identity, so no password sits on the host.

Create a KDS root key

Run this once per AD forest from a domain controller if you do not already have a KDS root key:

Add-KdsRootKey -EffectiveTime ((Get-Date).AddHours(-10))

Create the gMSA

On a DC, as a Domain Admin. Replace CONNECTORHOST with your connector host's computer name:

New-ADServiceAccount -Name ploy-connector -DNSHostName ploy-connector.corp.example.com -PrincipalsAllowedToRetrieveManagedPassword "CONNECTORHOST$"

The trailing $ in CONNECTORHOST$ is required because it identifies the computer object, not a user.

Install the gMSA on the connector host

On the connector host, as Administrator:

Install-ADServiceAccount ploy-connector
Test-ADServiceAccount ploy-connector

Test-ADServiceAccount must return True. If it returns False, the most common cause is that the host is not in PrincipalsAllowedToRetrieveManagedPassword. Re-run the gMSA creation step with the correct computer name.

Grant AD permissions

In standard AD configurations, authenticated users have read access to user, group, and OU objects, so the gMSA inherits read access automatically. If your environment hardens the directory, make sure the connector can Read on user, group, organizationalUnit, and container objects under your base_dn.

Write access is only needed if you enable write features. Scope rights to the OU subtree that holds the users and groups Ploy manages, and let inheritance carry them to objects inside it. Run this on a DC as someone who can edit that OU's ACL. Set $gmsa and $ouPath for your environment. Grant only the blocks you need:

PowerShell ACL script for write access
Import-Module ActiveDirectory

$gmsa   = "ploy-connector"
$ouPath = "AD:\OU=Ploy-Managed,DC=corp,DC=example,DC=com"

$sid = (Get-ADServiceAccount $gmsa).SID

$userObj    = [GUID]'bf967aba-0de6-11d0-a285-00aa003049e2'
$groupObj   = [GUID]'bf967a9c-0de6-11d0-a285-00aa003049e2'
$memberProp = [GUID]'bf9679c0-0de6-11d0-a285-00aa003049e2'
$allGuid    = [GUID]'00000000-0000-0000-0000-000000000000'

$Allow    = [System.Security.AccessControl.AccessControlType]::Allow
$Desc     = [System.DirectoryServices.ActiveDirectorySecurityInheritance]::Descendents
$ScopeAll = [System.DirectoryServices.ActiveDirectorySecurityInheritance]::All

$acl = Get-Acl -Path $ouPath

# group_management: write the 'member' attribute on groups in the subtree
$acl.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
    $sid,
    [System.DirectoryServices.ActiveDirectoryRights]::WriteProperty,
    $Allow, $memberProp, $Desc, $groupObj)))

# identity_management: create and delete user objects in the subtree
$acl.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
    $sid,
    [System.DirectoryServices.ActiveDirectoryRights]'CreateChild,DeleteChild',
    $Allow, $userObj, $ScopeAll)))

# identity_management: full control over the user objects themselves
$acl.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
    $sid,
    [System.DirectoryServices.ActiveDirectoryRights]::GenericAll,
    $Allow, $allGuid, $Desc, $userObj)))

Set-Acl -Path $ouPath -AclObject $acl

The member rule alone is enough for group_management. The two user-object rules are only needed where the connector provisions accounts. If managed users and groups live under different OUs, run the relevant block against each $ouPath.

Configure the connector

The service reads its config from C:\ProgramData\Ploy\Connector\config.yaml.

  1. Create the directory:

    New-Item -ItemType Directory -Force -Path "C:\ProgramData\Ploy\Connector"
  2. Copy the example and edit:

    Copy-Item "C:\Program Files\Ploy\Connector\config.example.yaml" "C:\ProgramData\Ploy\Connector\config.yaml"
    notepad "C:\ProgramData\Ploy\Connector\config.yaml"
  3. Fill in at minimum:

    • backend.key — your bearer key, or reference it with env://PLOY_CONNECTOR_KEY.

    • integrations.<slug>.credentials.url — your DC's LDAPS URL.

    • integrations.<slug>.credentials.base_dn — your domain root DN.

Example config using gMSA authentication:

backend:
  key: env://PLOY_CONNECTOR_KEY

integrations:
  corp-ad:
    type: active_directory
    enabled_features: [scan, group_management]
    credentials:
      url: ldaps://dc01.corp.example.com:636
      auth: windows_integrated
      base_dn: "DC=corp,DC=example,DC=com"

If you source the bearer key from an environment variable, set it at machine scope so the service sees it:

[Environment]::SetEnvironmentVariable('PLOY_CONNECTOR_KEY', 'ploy_ct_...', 'Machine')

Machine-scope environment variables only apply to new processes. Restart the service after changing one.

Install and start the service

From an elevated PowerShell:

cd "C:\Program Files\Ploy\Connector"
.\ploy-connector.exe install-service -service-account "CORP\ploy-connector$"
Start-Service PloyConnector
Get-Service PloyConnector

Replace CORP with your domain's NetBIOS name. The trailing $ is required for gMSAs. The service is registered with auto-start, so it survives reboots.

Verify the setup

  • Wait approximately 30 seconds, then open the Ploy admin UI and go to Integrations > Connectors. The connector should report as online with a recent heartbeat.

  • Tail the local log:

    Get-Content -Wait -Tail 50 "C:\ProgramData\Ploy\Connector\logs\connector.log"

    On a healthy startup you will see connector starting, then manifest registered, then periodic scan completed lines.

  • Check Windows Event Viewer under Applications and Services Logs > Ploy Connector. Errors are written here even if the log file path is unreachable.

Update or uninstall

To update, stop the service, replace the binary, and restart:

Stop-Service PloyConnector
Copy-Item .\ploy-connector.exe "C:\Program Files\Ploy\Connector\" -Force
Start-Service PloyConnector

Config and state persist across upgrades.

To uninstall:

.\ploy-connector.exe uninstall-service
Remove-Item -Recurse "C:\ProgramData\Ploy\Connector"
Remove-ADServiceAccount ploy-connector   # run on a DC

Use password-based authentication instead of gMSA

Use this only if your environment cannot use a gMSA. In config.yaml, set auth: simple and supply bind_user plus bind_password. The service can then run as LocalSystem; omit -service-account from the install command.

integrations:
  corp-ad:
    type: active_directory
    enabled_features: [scan]
    credentials:
      url: ldaps://dc01.corp.example.com:636
      auth: simple
      bind_user: "CN=ploy-connector,OU=Service Accounts,DC=corp,DC=example,DC=com"
      bind_password: env://AD_BIND_PASSWORD
      base_dn: "DC=corp,DC=example,DC=com"

We strongly recommend reading the password from an environment variable rather than embedding it in the file.

Corporate proxy and internal CAs

The connector honours HTTP_PROXY, HTTPS_PROXY, and NO_PROXY environment variables set at machine scope. User-info form http://user:pass@proxy:8080 is supported.

For internal CAs, set tls.ca_bundle in config.yaml to a PEM file path. Use tls.ca_bundle_append: true to add to the system root store rather than replace it.

Was this helpful?