5 minute read

Infrastructure Access Blueprint: Jenkins & OpenLDAP

This file details the structural architecture, data schema, and operational boundaries of the local engineering identity ecosystem.

1. Network Topology

Both core services run containerized inside Docker Desktop and bridge their application footprints over a dedicated software overlay network.

  • Docker Network Name: jenkins-ldap-net
  • Internal Resolution Targets:
    • Jenkins Server Endpoint: http://jenkins-server:8080
    • Directory Engine Service Socket: ldap://ldap-server:389

2. Directory Information Tree (DIT) Structure

The directory data layout uses a top-down tree schema to segregate accounts from transactional application groups.

dc=mycompany,dc=com (Root Context Base Domain)
 ├── uid=admin (Master Server Administrative Bind Identity)
 │
 ├── ou=Users (Structural Namespace Container for Person Profiles)
 │    ├── uid=alice.smith      (Admin Profile Role mapping)
 │    ├── uid=bob.jones        (Admin Profile Role mapping)
 │    ├── uid=charlie.brown    (Developer Profile Role mapping)
 │    └── uid=dana.white       (Developer Profile Role mapping)
 │
 └── ou=Groups (Structural Namespace Container for Role Assignment Profiles)
      ├── cn=jenkins-admins     (References admin profiles via explicit 'member' pointers)
      └── cn=jenkins-developers (References engineering profiles via explicit 'member' pointers)

3. Account Profiles Ledger

Common Name (cn) User ID (uid) Corporate Email (mail) Password String Assigned Access Profile Group
Alice Smith alice.smith alice.smith@mycompany.com Password123456 jenkins-admins
Bob Jones bob.jones bob.jones@mycompany.com Password123456 jenkins-admins
Charlie Brown charlie.brown charlie.brown@mycompany.com Password123456 jenkins-developers
Dana White dana.white dana.white@mycompany.com Password123456 jenkins-developers

4. Production Jenkins Config Settings Reference

These exact string parameters map user login tokens securely back against the OpenLDAP context tree.

Core Security Realm Settings

  • Server: ldap://ldap-server:389
  • root DN: dc=mycompany,dc=com
  • User search base: ou=Users
  • User search filter: uid={0}
  • Manager DN: uid=admin,dc=mycompany,dc=com

Group Mapping Specifications

  • Group search base: ou=Groups
  • Group search filter: (&(objectClass=groupOfNames)(cn={0}))
  • Group Strategy selection: Check only Search for LDAP groups containing user

Advanced Attribute Configurations

  • Display Name LDAP attribute: cn
  • Email Address LDAP attribute: mail

5. Matrix-Based Security Permissions Layout

Group: jenkins-admins

  • Assigned Rights: Global System Root Control (Administer)
  • Privilege Level: Can manage plugins, override system configuration nodes, adjust credentials pipelines, and spin up structural worker nodes.

Group: jenkins-developers

  • Assigned Rights: Operational Application Execution Boundaries
  • Permitted Grid Checkboxes:
    • Overall / Read
    • Dashboard / Read
    • Job / Build, Job / Cancel, Job / Read, Job / Workspace
    • Run / Replay, Run / Update
    • View / Read
  • Privilege Level: Restricted to application code deployment pipelines. System configuration submenus are safely hidden from these users.

Infrastructure Access Blueprint: Jenkins & OpenLDAP

This document details the configuration, structural layout, and access patterns established for the local containerized identity ecosystem.


1. Infrastructure Deployment (Docker Setup)

  • Jenkins Container: Running via jenkins/jenkins:lts on port 8080 [1]. Data is safely persisted on your Mac host via a Docker volume (jenkins_home) [1].
  • OpenLDAP Container: Running via vegardit/openldap on port 389. Data is bound directly to your local workspace (/ldap_data and /ldap_config) for easier local development access on macOS.
  • Container Networking: Both containers are securely bridged together via a custom Docker virtual bridge network named jenkins-ldap-net, enabling them to communicate directly using container names as internal domain addresses.

2. Directory Tree Layout (LDAP Hierarchy)

The directory database is structured dynamically using standard LDAP object identifiers:

dc=mycompany,dc=com (Root Domain)
 ├── uid=admin (Master Directory Manager Account)
 │
 ├── ou=Users (Structural Organizational Unit)
 │    ├── uid=alice.smith     (Pass: Password123456 | cn: Alice Smith     | Group: admins)
 │    ├── uid=bob.jones       (Pass: Password123456 | cn: Bob Jones       | Group: admins)
 │    ├── uid=charlie.brown   (Pass: Password123456 | cn: Charlie Brown   | Group: developers)
 │    └── uid=dana.white      (Pass: Password123456 | cn: Dana White      | Group: developers)
 │
 └── ou=Groups (Structural Organizational Unit)
      ├── cn=jenkins-admins     (Explicit Member Pointer: alice.smith, bob.jones)
      └── cn=jenkins-developers (Explicit Member Pointer: charlie.brown, dana.white)

3. Key Integration Resolutions

During development, we resolved several authentication and layout blocks:

  • Data Injection Intermission: Solved an issue where user records were initially missing (numResponses: 1) by manually forcing the LDIF injection after the server finalized its background boot sequence.
  • Lookup & Parameter Matching: Configured Jenkins to use the custom user filter uid={0} and mapped the missing displayName logic directly to the native common name (cn) attribute.
  • Email Attribute Patch: Fixed profile schema validation warnings by executing an ldapmodify injection script to add corporate mail attributes (e.g., alice.smith@mycompany.com) to all active users.
  • Group Mapping Calibration: Fixed group assignment failures by disabling the user-attribute memberOf checkbox Strategy and forcing Jenkins to use the container search filter (&(objectClass=groupOfNames)(cn={0})).

4. Active Access Control Profile

You are utilizing Matrix-based security to divide infrastructure duties according to standard enterprise guidelines:

  • jenkins-admins Row: Assigned full Administer root privileges. Users like alice.smith retain deep system, plugin, and hardware-node management control.
  • jenkins-developers Row: Assigned limited operations access (Overall/Read, Job/Build, Job/Workspace). Users like charlie.brown can execute and troubleshoot engineering pipeline builds, but system-wide settings pages are hidden from view.
#!/bin/bash

# 1. Define Local Paths for Persistence (macOS Bind Mounts)
DATA_DIR="$(pwd)/ldap_data"
CONF_DIR="$(pwd)/ldap_config"
NETWORK_NAME="jenkins-ldap-net"

echo "=========================================================="
echo " Starting OpenLDAP Development Environment Deployment"
echo "=========================================================="

# 2. Setup Network Topology
if ! docker network inspect "$NETWORK_NAME" >/dev/null 2>&1; then
    echo "Creating custom bridge network: $NETWORK_NAME..."
    docker network create "$NETWORK_NAME"
else
    echo "Bridge network $NETWORK_NAME already exists."
fi

# 3. Cleanup old deployment blocks
echo "Cleaning up stale container instances and local mount directories..."
docker rm -f ldap-server 2>/dev/null
sudo rm -rf "$DATA_DIR" "$CONF_DIR"

# Create clean host volumes
mkdir -p "$DATA_DIR" "$CONF_DIR"

# 4. Start the Server Container attached to the custom network
echo "Launching OpenLDAP Engine container..."
docker run -d \
  -p 389:389 \
  --name ldap-server \
  --network "$NETWORK_NAME" \
  --restart on-failure \
  -e LDAP_INIT_ORG_DN='dc=mycompany,dc=com' \
  -e LDAP_INIT_ROOT_USER_DN='uid=admin,dc=mycompany,dc=com' \
  -e LDAP_INIT_ROOT_USER_PW='newpassword123' \
  -e LDAP_INIT_ORG_NAME='MyCompany Corp' \
  -e LDAP_INIT_PPOLICY_PW_MIN_LENGTH='12' \
  -v "$DATA_DIR":/var/lib/ldap \
  -v "$CONF_DIR":/etc/ldap/slapd.d \
  vegardit/openldap:latest

# 5. Dynamic Health Check Loop (Replaces unreliable blind sleeps)
echo "Waiting for LDAP directory service socket to initialize..."
MAX_ATTEMPTS=30
ATTEMPT=1
while [ $ATTEMPT -le $MAX_ATTEMPTS ]; do
    if docker exec ldap-server ldapsearch -x -H ldap://localhost:389 -b "dc=mycompany,dc=com" >/dev/null 2>&1; then
        echo "LDAP Service engine is live and responding to internal queries!"
        break
    fi
    echo "Database initialization in progress... (Attempt $ATTEMPT/$MAX_ATTEMPTS)"
    sleep 2
    ATTEMPT=$((ATTEMPT + 1))
done

if [ $ATTEMPT -gt $MAX_ATTEMPTS ]; then
    echo "ERROR: OpenLDAP container timed out during initialization. Terminating."
    exit 1
fi

# 6. Inject Full Structure, Users with Mail, and Groups
echo "Injecting operational organizational units, user records, and role matrices..."
docker exec -i ldap-server bash -c 'cat <<EOF > /tmp/data.ldif
dn: ou=Users,dc=mycompany,dc=com
objectClass: organizationalUnit
ou: Users

dn: ou=Groups,dc=mycompany,dc=com
objectClass: organizationalUnit
ou: Groups

dn: uid=alice.smith,ou=Users,dc=mycompany,dc=com
objectClass: inetOrgPerson
uid: alice.smith
cn: Alice Smith
sn: Smith
mail: alice.smith@mycompany.com
userPassword: Password123456

dn: uid=bob.jones,ou=Users,dc=mycompany,dc=com
objectClass: inetOrgPerson
uid: bob.jones
cn: Bob Jones
sn: Jones
mail: bob.jones@mycompany.com
userPassword: Password123456

dn: uid=charlie.brown,ou=Users,dc=mycompany,dc=com
objectClass: inetOrgPerson
uid: charlie.brown
cn: Charlie Brown
sn: Brown
mail: charlie.brown@mycompany.com
userPassword: Password123456

dn: uid=dana.white,ou=Users,dc=mycompany,dc=com
objectClass: inetOrgPerson
uid: dana.white
cn: Dana White
sn: White
mail: dana.white@mycompany.com
userPassword: Password123456

dn: cn=jenkins-admins,ou=Groups,dc=mycompany,dc=com
objectClass: groupOfNames
cn: jenkins-admins
member: uid=alice.smith,ou=Users,dc=mycompany,dc=com
member: uid=bob.jones,ou=Users,dc=mycompany,dc=com

dn: cn=jenkins-developers,ou=Groups,dc=mycompany,dc=com
objectClass: groupOfNames
cn: jenkins-developers
member: uid=charlie.brown,ou=Users,dc=mycompany,dc=com
member: uid=dana.white,ou=Users,dc=mycompany,dc=com
EOF

ldapadd -x -D "uid=admin,dc=mycompany,dc=com" -w newpassword123 -f /tmp/data.ldif'

# 7. Hot-connect existing Jenkins container if present
if docker ps -a --format '' | grep -q "^jenkins-server$"; then
    echo "Connecting active 'jenkins-server' instance to network topology..."
    docker network connect "$NETWORK_NAME" jenkins-server 2>/dev/null || true
fi

echo "--------------------------------------------------------"
echo " Configuration Complete! Environment Is Fully Operational"
echo " Base Target Path DN : dc=mycompany,dc=com"
echo " Bind Manager Account: uid=admin,dc=mycompany,dc=com"
echo "--------------------------------------------------------"