Designing the directory for the long term: DIT layout principles, flat versus hierarchical trees, defining custom schema with OID allocation, data normalization, and safe migration patterns.

Most LDAP problems in production are born at design time: a DIT that doesn't scale, a schema that can't express the data, attributes forced into the wrong types. Episode 28 is about doing it right from the start: how to lay out the directory tree, when to define custom schema, how to allocate OIDs responsibly, and how to migrate safely when the design evolves.
The Directory Information Tree (DIT) is the skeleton of the directory. Five principles:
(employeeType=contractor) should have a filter-friendly attribute, not a deeper tree.ou=people, ou=groups are structural organization; membership is an attribute (member, memberOf), not a position in the tree.There are two main shapes:
Flat DIT — a single container holds everything:
dc=example,dc=com
├── ou=people
│ ├── uid=budi
│ └── uid=siti
└── ou=groups
└── cn=developersHierarchical DIT — containers by department or location:
dc=example,dc=com
├── ou=jakarta
│ └── ou=people
│ └── uid=budi
└── ou=bandung
└── ou=people
└── uid=siti| Aspect | Flat | Hierarchical |
|---|---|---|
| Search simplicity | one base, one subtree | must know the location |
| Moving users | modrdn to another DN | modrdn within a branch |
| ACL granularity | via attributes | via subtree |
| Replication split | needs partition | natural by branch |
| Recommend | for most orgs | for very large orgs with replication splits |
Rule of thumb: start flat. Add hierarchy only when a concrete need appears — a branch to replicate to a regional office, or a subtree with distinct ACLs.
The built-in schemas (core, cosine, inetorgperson) cover a lot. When they don't, define your own. A custom object class example:
dn: cn=employeeExt,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: employeeExt
olcObjectClasses: {0}( 1.3.6.1.4.1.4203.666.1.2 NAME 'employeeExt'
SUP top AUXILIARY
MUST ( employeeId $ hireDate )
MAY ( officeLocation $ managerUid $ costCenter ) )Rules for custom schema:
employeeExt holds employment data; don't mix it with network data.inetorgperson); add an auxiliary class that supplements it.OIDs (Object Identifiers) identify every attribute type and object class. Rules of allocation:
1 for attributes, 2 for object classes, 3 for other definitions.Enterprise OID arc: 1.3.6.1.4.1.<your-enterprise-number>
.1 attribute types
.2 object classes
.3 name forms / matching rulesAn OID register is as important as the schema file itself — without it, the next designer has no idea what 1.3.6.1.4.1.12345.1.17 means.
LDAP doesn't enforce normal forms like a relational database, but the discipline still applies:
uid=budi; departments, teams, and aliases reference that entry.mail and a custom email2 invites drift; use one authoritative attribute and derive others.caseIgnoreMatch for names) and stick to it.mail, telephoneNumber, title, employeeNumber exist; a custom attribute should be the exception, not the norm.Schema and DIT change over time; the danger is breaking running applications. A migration recipe:
slaptest -u -vNever change schema on production without a staging test and a rollback path.
Tip
Treat schema files as code: version them in git, review them in merge requests, and apply them through a pipeline (e.g. the CI in this project) that runs slaptest -u before touching a real server. The directory's schema is your data contract with every application.
In this episode 28 you learned schema design best practices: DIT principles and flat versus hierarchical layouts, defining custom attribute types and object classes with the proper structure, responsible OID allocation with a documented register, data normalization to avoid duplication, and safe additive migration with staging and rollback.
Key takeaways:
In the next episode, episode 29, we prove the directory is safe: compliance & security auditing — GDPR, PCI-DSS, SOC 2, HIPAA, and the audit workflow.