docs Directory Agent Protocol
Launch Nametag Get help

Directory Agent Protocol

This document describes Nametag’s protocol for communicating with a directory agent. A directory agent implements the basic functions to interact with a directory service, such as listing accounts, groups, and users, and performing recovery operations on them. Nametag has implementations of the agent protocol for various directories (e.g. Okta, OneLogin, Duo, Microsoft Entra ID, etc.). You can also implement your own agent to interact with a directory service that is not supported by Nametag.

For more details on directory agents, refer to Directory Agent

Agent to server protocol

A directory agent communicates with the Nametag server via a WebSocket connection over TLS. Implementations should connect to the Nametag server via WebSocket at wss://nametag.co/api/diragent?auth=AGENT_TOKEN.

The value for AGENT_TOKEN is provided in the output of the nametag directory agent register command. You must run this command prior to running a directory agent.

Note: The AGENT_TOKEN is a least-privilege token that only allows for agent connection and nothing else. You must use an agent token to connect to this socket, you cannot use an API key. Once the agent is connected, the server sends WebSocket frames consisting of a JSON-encoded DirAgentRequest. The agent responds with a WebSocket frame consisting of a JSON-encoded DirAgentResponse. The server may pipeline requests so that it sends a request before it receives a response from the prior request. The agent must take care to respond to requests in the same order they are received.

Agent to worker protocol

Nametag’s own implementation of the directory agent protocol is implemented as a main process that handles authentication and the WebSocket connection, and an extensible worker process that handles the actual directory operations. The worker process for official agents is implemented as a separate subcommand of the nametag directory agent command. You are free to implement your own worker commands and run them with nametag directory agent.

The main agent process communicates with the worker process by passing requests to the worker’s standard input and reading responses from the worker’s standard output. Each request is a JSON-encoded DirAgentRequest, terminated by a newline (\n). The worker must respond with a JSON-encoded DirAgentResponse terminated by a newline (\n).

The agent may have multiple requests in flight at the same time. The worker must respond to messages in the same order they are received.

Protocol Overview

Each request sent to the agent is a JSON object with exactly one of following fields set:

DirAgentRequest struct
configureDirAgentConfigureRequest (optional)

This field is set when the request is to obtain configuration information about the directory agent. The server sends this request to determine the capabilities of the directory agent.

list_accountsDirAgentListAccountsRequest (optional)

This field is set when the server needs to obtain a list of accounts. The request contains parameters to filter and limit the accounts returned.

get_accountDirAgentGetAccountRequest (optional)

This field is set when the server needs to get information about a specific account.

list_groupsDirAgentListGroupsRequest (optional)

This field is set when the server needs to get a list of all possible groups. The request contains parameters to filter and limit the groups returned.

perform_operationDirAgentPerformOperationRequest (optional)

This field is set when the server needs to perform a recovery operation on an account, or with DryRun set when the server wants to test the ability to perform the operation without actually performing it.

pingboolean (optional)

The server will periodically send a request with this field set to true in order to test the connection to the directory agent. The agent should respond with an empty DirAgentResponse.

The response from the agent is a JSON object with exactly one following fields set:

DirAgentResponse struct
configureDirAgentConfigureResponse (optional)

This field should be set by the agent when the request has configure set to return the results of the request. If an error occurs, the agent should not set this field but should set error instead.

list_accountsDirAgentListAccountsResponse (optional)

This field should be set by the agent when the request has list_accounts set to return the results of the request. If an error occurs, the agent should not set this field but should set error instead.

get_accountDirAgentGetAccountResponse (optional)

This field should be set by the agent when the request has get_account set to return the results of the request. If an error occurs, the agent should not set this field but should set error instead.

list_groupsDirAgentListGroupsResponse (optional)

This field should be set by the agent when the request has list_groups set to return the results of the request. If an error occurs, the agent should not set this field but should set error instead.

perform_operationDirAgentPerformOperationResponse (optional)

This field should be set by the agent when the request has perform_operation set to return the results of the request. If an error occurs, the agent should not set this field but should set error instead.

errorDirAgentErrorResponse (optional)

This field should be set by the agent when the request has failed. The code fields tells the server the general reason for the error.

Error Handling

In the event of an error, the agent must respond with a DirAgentResponse having the error field set.

DirAgentErrorResponse struct
codeDirAgentErrorCode

An error code that describes the general reason for the error.

messagestring

A human-readable message that describes the error in more detail.

The code field must have one of the following values:

DirAgentErrorCode enum
service_authentication_failed

The agent was unable to authenticate to the directory service. The administrator should be prompted to reconfigure authentication.

permission_denied

In response to perform_operation, the agent has determined that the operation should not be allowed due to its own policy.

account_not_found

The account specified in the request was not found.

configuration_error

The agent is not configured correctly. The administrator should be prompted to reconfigure the agent.

unsupported_account_state

In response to perform_operation, the agent has determined that the account is not in the proper state, e.g. attempting to unlock an account which is not locked.

internal_error

The agent encountered an error in processing the request that does not fit into one of the other categories.

Configure method

The server invokes this method to assess the agent’s capabilities. The agent should reply with the supported capabilities and, to the extent possible, confirm that its configuration is valid. For example, the agent could issue an innocuous API call to the directory service to verify that the configured credentials are valid.

Request:

DirAgentConfigureRequest struct

Response:

DirAgentConfigureResponse struct
immutable_idstring

Uniquely identifies the agent.

traitsDirAgentTraits

Describes the capabilities of the directory agent.

A Note on immutable_id:

The immutable_id returned as part of the configure response identifies an agent with the directory. It is up to the agent to generate a string that will tie the type of the underlying agent with the nametag custom directory. When an agent first connects to a new custom directory, the immutable_id that nametag receives as part of the configure response is associated with the directory. Subsequently, only agents that return that immutable_id will be allowed to connect to that custom directory.

The traits field contains the following fields:

DirAgentTraits struct
namestring

The display name of the directory agent. This is the name that will be displayed to administrators and end-users in the user interface, for example "Okta" or "ExampleCorp".

can_get_temporary_passwordboolean (optional)

Indicates whether the agent can create a temporary password for an account, allowing the user to log in for a limited time.

can_get_password_linkboolean (optional)

Indicates whether the agent can generate a pre-authenticated link that leads the user to a site (typically provided by the directory service) that the user can use enter a new password.

can_remove_all_mfaboolean (optional)

Indicates whether the agent can remove all MFA factors from an account so the user can re-enroll their MFA device.

can_get_mfa_bypass_codeboolean (optional)

Indicates whether the agent can generate a bypass code that the user can use to sign in in place of their MFA device. Typically after using a bypass code the user will be able to enroll a replacement MFA device.

can_unlockboolean (optional)

Indicates whether the agent can unlock an account that has been locked due to too many failed login attempts.

can_get_temporary_access_passboolean (optional)

Indicates whether the agent can generate a temporary code that the user will use to log in temporarily without revoking their existing password or resetting any MFA devices.

can_update_accounts_listboolean (optional)

Indicates whether the directory service supports tracking the last modification time of the account list. If supported, the server may set updated_after in list_accounts to indicate the agent should report only accounts that have been updated since that time.

ListAccounts method

The server calls this method to determine which accounts are present in the directory. Because directories can contain thousands of accounts, the agent return accounts in pages. The server will call this method multiple times to retrieve all accounts. The cursor field is used to track the progress through the list of accounts.

There is no hard limit on the number of accounts that can be returned in each page, but the agent should return a reasonable number of accounts to avoid reliability problems. Many directory services themselves paginate the list of accounts and have recommended page sizes, which can be used as the page size when implementing this method. Nametag’s own implementations of this protocol returns at most 250 accounts per page, but the exact appropriate page size may depend on the directory service being used.

If the agent supports the can_update_accounts_list trait, the server may set updated_after to a timestamp. The agent should return only accounts that have been updated after this timestamp. While iterating the list of accounts using cursor, the server will set the same updated_after for each request.

Request:

DirAgentListAccountsRequest struct
updated_afterRFC 3339 date-time string (optional)

Only return accounts that have been updated after this time.

cursorstring (optional)

If present, the server is requesting a continuation of a previous list of accounts. The value will be the one most recently returned in the next_cursor field. The format of this value is determined by the agent. The server treats this value as opaque and passes it back to the agent in the next request. To start at the beginning of the list, the server will omit this field.

Response:

DirAgentListAccountsResponse struct
accountsList of DirAgentAccount

The accounts that the agent has discovered.

next_cursorstring (optional)

If there are more results to return, the agent should set this field to the value that should be passed back to the server in the next request. If there are no more results, the agent should omit this field.

Each item in the accounts field is a DirAgentAccount object:

DirAgentAccount struct
immutable_idstring

A unique identifier for the account that will not change over time. In many directory services this is an UUID or similar opaque identifier.

idsList of string

A list of account identifiers, such as email addresses or usernames. These identifiers are used to select accounts for various operations. Many directory services have multiple identifiers for an account, such as alternate email addresses and aliases. Each identifier that might be reasonably used to identify an account should be placed here.

namestring

The name of the person that holds the account. This is the value that Nametag uses to match against the person's verified government ID. This is the name that will be displayed to administrators and end-users in the user interface.

groupsList of DirAgentGroup (optional)

A list of groups that this account belongs to.

birth_datestring (optional)

If the directory service has a birth date for the account, it should be included here. This is used to match against the person's verified government ID. The birth date can take various forms, including a RFC 3339 date string (YYYY-MM-DD), or a specially constructed hash.

updated_atRFC 3339 date-time string (optional)

The time when this account, or its group membership, was last modified. This field is required if can_update_accounts_list is set to true in the agent's traits. The server will track the greatest updated_after returned by an iteration and provide that value back to subsequent iterations. The agent should return only accounts that have been updated since that time.

The groups field contains a list of groups that an account is a member of.

DirAgentGroup struct
immutable_idstring

An identifier for the group that will not change over time. In many directory services this is an UUID or similar opaque identifier. If the directory service doesn't distinguish between group identifiers and names, use the same value here as for name.

namestring

The group's display name.

kindstring

Some directory services have different kinds ways of grouping users, each of which can be considered a group for Nametag's purposes. For example, you might have "security groups", "roles", "administrative units", etc. This field should be set to the kind of group that this is. The semantics of this field are up to the agent. Nametag treats it as opaque.

GetAccount method

The server calls this method to retrieve the details of a specific account.

Request:

DirAgentGetAccountRequest struct
refDirAgentAccountRef

Specifies which account to fetch information about.

A DirAgentAccountRef object is a reference to an account. Exactly one of the fields in this object must be specified.

DirAgentAccountRef struct
immutable_idstring (optional)

The immutable identifier of the account to fetch information about.

idstring (optional)

One of the identifiers of the account to fetch information about. This is typically an email address or username.

Response:

DirAgentGetAccountResponse struct
accountsList of DirAgentAccount

Information about the accounts that match the specified reference. If you specified an immutable_id in the request, the response will contain at most one account. If you specified an id in the request, because the same id can be present on multiple accounts, the response may contain multiple accounts. Unlike the list_accounts method, the accounts in this list should contain groups information, even if it requires the agent to perform additional work to determine group membership. If no accounts match, this list should be empty.

If no accounts match the specification, the agent must respond with an empty list, and must not set an error code.

ListGroups method

The server calls this method to determine which groups are present in the directory. Because directories can contain thousands of groups, the agent return groups in pages. The server will call this method multiple times to retrieve all groups. The cursor field is used to track the progress through the list of accounts.

There is no hard limit on the number of groups that can be returned in each page, but the agent should return a reasonable number of groups to avoid reliability problems. Many directory services themselves paginate the list of groups and have recommended page sizes, which can be used as the page size when implementing this method. Nametag’s own implementations of this protocol return at most 250 groups per page, but the exact appropriate page size may depend on the directory service being used.

Request:

DirAgentListGroupsRequest struct
name_prefixstring (optional)

The agent should return only groups whose name starts with this prefix.

max_countinteger (optional)

The maximum number of groups to return. If the agent has more groups than this, it should return the first max_count groups in lexicographic order by name. Note: this is not the maximum number of groups per page, this is simply a signal that the server will discard any groups beyond this number.

cursorstring (optional)

If present, the server is requesting a continuation of a previous list of groups. The value will be the one most recently returned in the next_cursor field. The format of this value is determined by the agent. The server treats this value as opaque and passes it back to the agent in the next request. To start at the beginning of the list, the server will omit this field.

Response:

DirAgentListGroupsResponse struct
groupsList of DirAgentGroup

The groups that the agent has discovered.

next_cursorstring (optional)

If there are more results to return, the agent should set this field to the value that should be passed back to the server in the next request. If there are no more results, the agent should omit this field.

PerformOperation method

The server calls this method to perform a recovery operation (e.g. resetting a password) on an account, or to test if an account is eligible for an operation. The agent should respond with the results of the operation, or an error if the operation cannot be performed.

Request:

DirAgentPerformOperationRequest struct
operationDirAgentOperation

The operation to perform on the account.

account_immutable_idstring

The immutable identifier of the account to perform the operation on.

dry_runboolean (optional)

If set to true, the agent should not actually perform the operation, but should test if the operation is likely to succeed, to the best of its capability. If the operation is not possible, the agent should set error in the response with an appropriate error code.

The operation field specifies the operation to perform. It has one of the following values:

DirAgentOperation enum
get_temporary_password

Generate a temporary password for the account.

get_password_link

Generate a pre-authenticated link that leads the user to a site where they can enter a new password.

remove_all_mfa

Remove all MFA factors from the account to permit a user to re-enroll in MFA.

get_mfa_bypass_code

Generate a bypass code that the user can use to sign in in place of their MFA device.

unlock

Unlock the account that has been locked due to too many failed login attempts.

get_temporary_access_pass

Generate a temporary access pass for the account.

Response:

DirAgentPerformOperationResponse struct
temporary_passwordstring (optional)

If the operation was get_temporary_password, this field should contain the temporary password that the user can use to log in and set a new password.

password_linkstring (optional)

If the operation was get_password_link, this field should contain a pre-authenticated link that the user can use to set a new password.

mfa_bypass_codestring (optional)

If the operation was get_mfa_bypass_code, this field should contain the bypass code that the user can use to sign in in place of their MFA device.