Middleware provides a read-write interface to the Enterprise Directory via a REST API located at https://apps.middleware.vt.edu/ws/v1.
REST API Client Example
The following code sample in Python provides a simple but complete usage overview that covers authentication and reading/writing data:
REST API Operations Reference
Please see the following reference for a complete list of REST API operations:
The following sections describe usage requirements and conventions that govern all REST API operations.
There are a couple prerequisites that prospective clients need to consider before attempting to consume the REST API.
Enterprise Directory Service
An ED Service provides the security principal and credential to invoke REST API operations. An ED service is typically credentialed with an X.509 certificate issued by the Middleware CA, but may also have a password credential issued under approved circumstances (see below).
Authorization to Invoke REST API
An ED Service must be entitled to invoke various REST API operations. The entitlements required to invoke various operations are listed in the link:rest-api-operations[Operation Reference]; please make note of what operations you want to invoke and document them by endpoint URI on your ED Service request.
The following conventions are intended to facilitate using the API. We recommend committing these conventions, which we have found improves users’ ability to anticipate URIs and JSON document field names.
URI Naming Conventions
- Resource URIs are named with a plural resource collection and end in a unique identifier, for example, /v1/persons/[uid], /v1/groups/[uugid].
- Action URIs have singular path parts and end in a verb, for example, /v1/replication/banner/consume, /v1/password/validate.
URIs Are Case Sensitive and Lower Case
All URIs are case sensitive and canonically lower case in terms of paths and parameter names that appear in the querystring. Parameter values that appear in the querystring may of course be upper case to support searching for case-sensitive fields like person names, but many data elements are canonically lower case as well, such as uupids and uugids and these are searched in a case-insensitive fashion.
JSON Data Is Case Sensitive and Mixed Case
The fields in JSON documents are named using the mixed-case convention of the Enterprise Directory LDAP schema in order to provide consistency between data elements regardless of what interface is used (LDAP vs HTTP).
Three authentication methods are supported and are listed in order of recommended practice:
- HTTP Bearer token authentication via signed JWT
- Client TLS
- HTTP Basic authentication using an ED service password
Password-based authentication is discouraged; consequently ED services do not have passwords unless specifically requested and authorized by the IT Security Office.
HTTP Bearer Auth
The HTTP Bearer token authentication method provides the best balance of security and usability to clients:
- Strong security via digital signatures
- Excellent cross-platform support
- Precise control over token validity period
A signed JSON Web Token (JWT) provides most of the advantages above and is simply a JSON document that is prepended with a digital signature algorithm header and to which a digital signature is appended; all parts are base-64 encoded.
# Line breaks added for readability # Parts separated by "." character eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ2dC1zZXJ2aWNlIiwiaWF0IjoxNDc2MTgwMTU5LCJleHAiOjE0NzYxODE5NTl9. QQD51aFptIc9u66iqgxJYyXl8dYP8kPanLtlVOPfeXSk5u_BeZ__QBjEKlCW2TjfFeF8SNHsC6zFMiY- QJIowaYXaYscJQJhl8FSiOUv0M46DJYYGxlHzdbGS9mUmLw25K1bMlUjSG6phNTxlNogCfUyCrIJ92TlLrpYNegQ78DDLvbxkbTTGdj_6Doe_Q- oVQ3k2tse6aZaMcGa99JY2imO06RCXt7y9n7gUYFliCwKdhemrPApe-6Sgb-jnxNAIAVzOd42_GHJl9DrFOsRCeNO2hbwQGRszSankj8ZFZEVh- cy0AFcCxGAdRC9jM3jmfXy32g844CWsevHV2OJCw
The token above contains the following JSON document, which you can see by pasting the token (with line breaks removed) into the jwt.io debugger:
The fields of the JSON document follow an established vocabulary called claims, of which four are recognized for Enterprise Directory Web services:
- iss - REQUIRED DN of the ED-ID service that issued (signed) the token, e.g. uusid=vt-service,ou=services,dc=vt,dc=edu
- iat - REQUIRED creation (Issued At) date of token
- exp - REQUIRED expiration date of token
- sub - OPTIONAL DN of the person to impersonate when invoking the service, e.g. uid=12345,ou=people,dc=vt,dc=edu
The presence of a sub claim indicates an impersonation token. The token may contain other claims but they will be ignored.
The validity period of the token is defined as the period of time between the iat and exp claims. There are some important policy controls on validity periods that are enforced at authentication time:
- Normal tokens MAY define a validity period of no more than 365 days.
- Impersonation tokens MAY define a validity period of no more than 30 days.
- The iat claim MAY be up to 30 seconds in the future to account for clock drift between client and server.
Tokens that violate the above policy constraints will be rejected when presented for authentication.
The token MUST be signed with the private key corresponding to a valid (e.g. not expired) ED service certificate and whose service exists and is active in the Enterprise Directory. The signature MUST be produced using the RS256 algorithm.
In general JWT bearer tokens MUST NOT be shared since a bearer token is by nature a self-contained authentication token; whoever bears the token may authenticate and access services as the principal identified in the token.
The exception to this strict requirement is an impersonation token that bears the sub claim. An impersonation token is signed by the private key of the issuer and identifies a person principal named in the sub claim. Thus the service that issued and signed the token is impersonating the named principal.
Impersonation tokens MAY be shared, but care must be taken to share the impersonation token exclusively with the principal named in the sub claim; it MUST NOT be shared with other parties due to its bearer nature.
Despite the need for care, impersonation tokens when used correctly are quite powerful. They can be shared with browser clients such that the bearer token can be passed via Authorization header in script-driven HTTP requests, allowing browser clients to directly interact with the Middleware REST API instead of through a facade or proxy that handles authentication. In the future the Middleware REST API may support OAuth for a more complete and standards-compliant security framework that satisfies the same need.
Sample Shell Script to Generate JWT
export TOKEN=$(gen-bearer-token.py your-service /path/to/your-service.key) curl -v -XGET -H"Authorization: Bearer $TOKEN" https://apps.middleware.vt.edu/ws/v1/groups/your.group
The example code above demonstrates how to construct a valid JWT for use with Enterprise Directory Web services. A python script is available to facilitate generating tokens.
Client TLS Auth
The Enterprise Directory Web services support client TLS authentication with an ED service certificate issued by the Middleware CA, which is chained to the Virginia Tech Root CA. There are two primary configuration points for client TLS authentication:
- Client authentication credentials (private key + X.509 certificate containing public key)
- Server trusted certificates (one or more root certificates)
The authentication credentials MUST be the ED service certificate (issued by the Middleware CA) and corresponding private key. Middleware CA certificates have a 2-year validity period and must be renewed periodically. Only a single trusted CA certificate is required to communicate with the RESTful Web services.
Issuer: OU=GlobalSign Root CA - R3, O=GlobalSign, CN=GlobalSign Validity Not Before: Mar 18 10:00:00 2009 GMT Not After : Mar 18 10:00:00 2029 GMT Subject: OU=GlobalSign Root CA - R3, O=GlobalSign, CN=GlobalSign -----BEGIN CERTIFICATE----- MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK 6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH WD9f -----END CERTIFICATE-----
The servers hosting Enterprise Directory Web services are configured for optional client authentication. If a valid client certificate is not provided in the TLS handshake, the connection will proceed with an anonymous client authentication context to allow other mechanisms such as HTTP Bearer or HTTP Basic to proceed.
HTTP Basic Auth
Clients may authenticate with a password credential provided by HTTP Basic authentication if and only if the corresponding ED service has been configured with a generated password. The following code snippet demonstrates HTTP Basic authentication.
Enterprise Directory Resources
There are 6 kinds of resources in the Enterprise Directory Web services that correspond to the branches of the Enterprise Directory LDAP schema. A resource is accessible via an HTTP request made to a URI that identifies the kind of resource and its unique identifier; thus URIs follow the convention +/[api_version]/[resource_collection_name]/[unique_id]+.
There are two related URIs for every resource type:
- Resource collection URI (create and bulk fetch resources)
- Resource URI (fetch, update, delete resource)
The resource URI is defined by appending the unique ID to the resource collection URI.
|Person||ou=people||uid||/v1/persons/[uid]||person demographic data|
|Account||ou=people||pid||/v1/accounts/[pid]||person PID account details|
|Mailbox||ou=people||address||/v1/mailboxes/[address]||person email account details|
|Service||ou=services||uusid||/v1/services/[uusid]||uusid is the service name|
|Group||ou=groups||uugid||/v1/groups/[uugid]||uugid is the group name|
|Entitlement||ou=entitlements||uid||/v1/entitlements/[uid]||uid is a numeric identifier|
All resources contain numerous fields, and in many cases some fields are expensive to fetch and unnecessary for the use at hand. In order to balance breadth and depth cases, many fields are marked optional and must be explicitly requested when a resource is fetched via the optional with querystring parameter included in the GET request. The syntax for requesting optional fields is follows:
where section1, section2, and section3 are sections denoting a field or field set
The names of optional field sections are documented in the resource schemas that follow and in many cases the section name is the field name since the field is naturally lowercase, otherwise a brief lowercase name is used to describe the section. The all section name is shorthand for requesting that all optional fields be included in the fetched resource. Use of this capability is discouraged for bulk queries that may return large result sets.
The person resource provides information about the identifying characteristics of a Virginia Tech affiliate: name, birthdate, afffiliations, employment information, and student information. It has the following schema (in YAML to allow for comments).
The account resource provides details on the person’s PID account. The account resource is intended primarily for viewing account state and managing credentials.
There is one mailbox resource for each type of ED email account but all share the same fields. Email accounts support aliases such that a single account may receive mail sent to multiple addresses. Additionally, forwarding addresses are supported for FE accounts such that mail sent to the account is not stored but forwarded to another address.
There are several types of ED email accounts based on the purpose and backing system:
|GE||Google (vt.edu)||Virginia Tech email account|
|CE||Google (vtc.vt.edu)||Carilion email account|
|GAE||Google (vt.edu)||Virginia Tech auxiliary email account|
|CAE||Google (vtc.vt.edu)||Carilion auxilary email account|
|FE||Virginia Tech (vt.edu)||Virginia Tech forward-only email account|
Auxiliary accounts are supplemental accounts that may be requested and granted for special circumstances. Forward only accounts are special purpose accounts that expose a specific Virgnia Tech email address for mail to be forwarded to another account, often a Virginia Tech Exchange account. Most users have only a single GE account. Carilion affiliates may have both CE and GE accounts.
An Enterprise Directory service is a credentialed account not associated with a person that is intended to be used to access and manage Enterprise Directory resources by an application, service, or system. Services have strong public key credentials by default, though they may also have complex passwords if requested and authorized by the IT Security Office. Services are explicitly authorized to view and modify data via Enterprise Directory Web services; they have the following structure.
An Enterprise Directory group is a container for people, services, and groups that may be used by its members for communication, collaboration, and/or authorization. Groups have a controlled namespace where each namespace part is separated by a dot. The first namespace part is called the stem and must be created via service request; groups are subsequently self-service with respect to creation and membership management. Groups have 5 roles associated with them:
|Role||View Members||Manage Members||Create Groups||Designate Managers||Email Notifications|
All roles except viewer may be fulfilled by either an account (i.e. person) or a service (i.e. machine) to allow both human users and software agents to communicate, collaborate, and participate in authorization. Only services may fulfill the viewer role, which is intended to permit a software agent to see the group when its suppression flags are enabled. Groups are private by default but may be made public by toggling suppression flags, suppressDisplay and suppressMembers. If these flags are enabled, the group and its members are hidden from anonymous LDAP queries against the ou=groups branch of the Enterprise Directory. Suppressed groups can be made visible by setting a service viewer and using that service principal to bind and query the directory.
Groups have expiration dates by default to encourage active maintenance; email notifications include periodic email expiration notifications at a minimum. Group members (in any of the roles above) MAY have expiration dates. A common use case for member expiration is to enforce temporary authorization policy on a party whose affiliation has a known end-date; for example, end of term for a student participating in a research project.
An Enterprise Directory entitlement is an authorization granted to an account or service to access data or perform an action. An ED service belonging to an application, service, or system grants the entitlement to an account or service and interprets its meaning when the grantor presents its. Entitlements have 4 associated roles:
- Manager - the service that created the entitlement
- Member - the account or service to which the entitlement was granted
- Sponsor - optional account (owned by a person) that sponsored granting the entitlement
- Viewer - one or more arbitary third party services that may view the entitlement
Entitlements are naturally sensitive and may be viewed only by the parties involved; third parties may view entitlements only when explicitly permitted via the viewers field.
Entitlements have an open namespace, but are encouraged to following the URN specification. A URI, which is a specialization of a URN, has a good balance of structure and flexibility to accommodate most cases. Consider the following example:
The entitlement above belongs to the factory application and entitles the grantor to perform the activate action of the widgets section with data field=value. It’s a contrived example, but explains how entitlements can cover both actions and data.
Entitlements are immutable except for the following fields that may be modified:
The entitlement should be removed and recreated if other fields require modification.