DocumentationRelease Notes
Log In
Documentation

SDK FOR ENDPOINT CREDENTIAL MANAGER GUIDE

This guide gives you the information you need to develop your own plugin that integrates with Secure Remote Access (SRA) products. After reading, you should understand how to handle plugin development, how integrations can solve use cases, and how plugins fit into the typical SRA user workflow.

Solution architecture

What is the Endpoint Credential Manager?

ECM is a .NET application installed and run as a Windows Service on a Windows host. It provides external credentials, typically from a password vaulting product such as BeyondTrust Password Safe to SRA users. The ECM knows how to communicate with an SRA site via a set of pre-defined messages and formats, known as the ECM Protocol. The ECM then employs a plugin architecture which requires any plugin to implement a specific set of functionality. The details of that implementation, such as the interaction with the password vault solution, are up to the plugin and separate from the ECM.

Until now, these implementations and plugins were solely written and maintained by BeyondTrust. The ECM was responsible for most of the primary work, from searching and loading plugin libraries to collecting, storing, and loading configurations for both the ECM and individual plugins.

By creating the ECM software development kit (SDK), the plugins now have some of these responsibilities. This provides a plugin more flexibility in the tools. It also allows the ECM to fill its primary role, without the added complexities of dealing with the specifics of configuration and logging.

As of the initial release, the ECM SDK consists of:

  • Developer guides and documentation
  • .NET 8 library, which contains components of the actual SDK
  • Example plugin project

Both the library and the sample plugin are written in .NET (specifically C#) and target the .NET 8 runtime, which allows cross-platform development and deployment.

This guide assumes development in Microsoft Visual Studio, however the integrated development environment is the developer's choice.

ℹ️

Note

For approved partners, BeyondTrust provides a separate package of resources which contain the ECMService, the gateway component between SRA and the plugin. While these resources are not required for plugin development, they are required for end-to-end testing.

SRA+ECM: Workflow and communications

Configuring and running the ECM Service opens a connection to the specified SRA site. All communication securely takes place over TCP 443 using the site's SSL certificate. The exception to this are sites using a non-standard configuration or traffic proxied on a non-standard port.

Once connected, the ECM and site perform a typical SSL handshake. The ECM ensures the site supplies a valid, matching cert. Authentication happens via OAuth2 Client ID and Secret. The ECM and site then negotiate ECM Protocol version.

The ECM service does support multiple versions of the ECM Protocol. As future protocol versions are released, every effort will be made to maintain backward compatibility.

ℹ️

Note

The negotiated protocol version may affect the features available to the ECM and plugin, such as types of requests, or the data passed between SRA and the ECM.

The ECM also reports the supported plugin capabilities during connection. The individual plugins define the capabilities and dictate what features are available.

For example, if a plugin does not reportedly support the Endpoint Search capability, then the SRA site does not route any requests for external endpoints to that instance, regardless of what the implementation supports.

After the initial sequence is complete, the SRA sends two types of messages:

  • A simple ping-pong style message to keep the connection alive and ensure it is still active. The ECM service handles this message with no plugin involvement.
  • A less-frequent health-check query associated with a plugin capability flag. If the plugin does not need to handle these requests and reports that it does not support them, it does not receive them. The plugin takes the necessary steps to assess its health status and return a healthy or not healthy status back to the ECM and SRA.

User action dictates everything else. If a user does something within SRA that corresponds to one of the use cases below, an appropriate request routes to the ECM. The plugin then provides the expected response in a reasonable time.

Use cases

The use cases below correspond to user actions within SRA. There are currently three categories of actions for which a plugin may provide implementations:

Credential actions

These actions all relate to the handling of credentials from an external source. They are the most common use cases.

  • Retrieve a list of credentials - (Required) Occurs when the user chooses a Jump Item and initiates a session to the target system. The plugin retrieves a list of credentials that are either queried or filtered based on the supplied information about the user and system they're connecting to. Only basic credential information (an ID and display value) is required.
  • Retrieve a specific credential - (Required) A user selects a credential from the list. The plugin uses the supplied session information and the selected credential ID to retrieve and check-out that credential. It returns and injects the credential into the session.
  • Release the credential - The SRA site notifies the ECM when the session ends. Users can perform any clean-up or check-in actions to release the credential and allow other users to access it.

ℹ️

Note

The actions marked Required are expected behaviors for any plugin implementation.

Endpoint actions

This action supplies ad-hoc Jump Items to SRA. This action is less common, but can be useful if the solution manages system information and supplies the necessary details to create items.

  • Retrieve a list of endpoints - If the SRA site has the feature enabled and the plugin reports that it supports endpoint search, users can then search for External Jump Items. Searches result in this request type. An exception is the plugin finding and returning a list of systems and endpoints presented as ad hoc Jump Items, allowing users to open sessions.

Session actions

These less common actions target a system that manages both systems and credentials. The system may also have a built-in capability to facilitate and audit sessions.

These actions all relate to External Jump Items, supplied by the Endpoint Action use case above. Requests corresponding to these use cases will not be sent for normal (SRA-managed) Jump Items.

  • Start session - Notifies the system that the user has requested to start a session.
  • Session started - Notifies the system that the session has started.
  • Session complete - Notifies the system the session has ended.

Create a plugin

  1. In Visual Studio, create a Worker Service project .
  2. Name the project and select .NET 8.0 (LTS) or newer for the target framework. Update additional settings and options as needed.
  3. After creating the project, you have two classes and source files: Worker.cs. and Program.cs
    1. Program.cs is the application's entry point (what is run when the app is started).
    2. Discard Worker.cs class. For our implementation, the ECMService is the IHostedService implementation and takes the place of the Worker class. It also derives from Microsoft.Extensions.Hosting.BackgroundService.
  4. Add a new class as a controller to handle the various requests routed to the plugin from the ECM. This class is discussed in the next section and is implemented with the plugin contract defined by the SDK - IECMPlugin.

Implementing IECMPlugin

The plugin contract, IECMPlugin, defines a set of properties and methods through which the ECM Service can communicate with a given plugin. While the interface defines all of these items, not all require an implementation. Instead, they can have an empty implementation or throw an exception.

MVP (Minimum Viable Product)

Your plugin must implement the informational properties for Name and Version, as well as the Credential Action methods for FindCredentialsForSessionAsync and GetCredentialForInjectionAsync. All other properties and methods are optional.

Informational properties and general functionality

There are a few general properties and methods that are not directly related to any specific actions that a plugin might support.

Properties

  • Name - The proper name of the plugin (ex: CompanyName ProductName Plugin)
  • Description - An optional description of the plugin or integration
  • Version - The version of the plugin to be updated with each release and can aid in debugging and support

General methods

  • GetPluginCapabilities - This method without parameters is called when the ECM Service negotiates the connection details with the SRA site. The result is the PluginCapabilities object, which indicates to the SRA site which operations the plugin supports.

ℹ️

Note

If a plugin reports that it does not support a given capability, the SRA site does not route requests of that type to the ECM or plugin instance.

  • PerformHealthCheckAsync - The SRA site calls this method without parameters to ensure the ECM and plugin are in a healthy state and ready to handle any requests. This should be implemented for most plugins.

    The SRA checks on health status once per minute, so implementation is efficient and identifies any issues which may prevent the plugin from handling requests. This operation may involve verifying the plugin's configuration and required fields. It could also include smarter checks, such as testing communication with the password vaulting system to verify configuration, network connectivity, and correct authentication details.

ℹ️

Note

If a health check fails and a plugin reports an unhealthy state, the SRA site continues to query for health status on the same interval, but does not route any other requests to the ECM or plugin instance until the health check passes.

Credential actions

ℹ️

Note

A capabilities flag indicates whether the plugin supports this feature. If the flag is false, the SRA site does not send these requests.

These methods give plugins the ability to handle various credential-related requests that may be generated in the course of an SRA session:

  • FindCredentialsForSessionAsync - This method takes an SRASession object containing basic information about the session, including the SRA user and Jump item, and retrieves a list of credentials available to the user and applicable to the endpoint. The credentials are in the form of CredentialSummary objects. There is no need to retrieve full sets of credentials, as the only information required is a display value (what SRA users see in the credential chooser) and an ID. These are passed back to the plugin when the user selects a credential from the list to inject.

ℹ️

Note

Because the ECM and plugins are generally stateless, it is important that the ID for each returned record be sufficient to identify and retrieve the full record on following calls. This means the plugin should construct a composite value for the ID, which is comprised of necessary information for additional actions.

For example, if the password vaulting system requires an internal_id as well as a credential_group in order to check out the credential, then the plugin may construct an ID that looks like <internal_id>|<credential_group> (ex: 795|QAServers).

  • GetCredentialForInjectionAsync - This method also takes an SRASession object, but there is no endpoint information included, only session and SRA user information. It takes a credentialId, which is the ID portion of the CredentialSummary item the user selected for injection. The plugin retrieves a specific credential to be used to authenticate to the endpoint. These are returned as CredentialPackage objects.
  • ReleaseCredentialFromSessionAsync - This method also takes an SRASession object, but there is no endpoint information included, only session and SRA user information. It takes a credentialId, which is the ID portion of the CredentialSummary item the user selected for injection, as well as a Unix timestamp value. This value indicates when the session ended. The password vaulting system requires this information. The plugin notifies the password vaulting system that the integration is no longer using the credential.

Endpoint actions

This method allows plugins to handle requests that provide managed endpoint information to SRA. SRA then uses this information to create ad-hoc or External Jump Items:

ℹ️

Note

To utilize this functionality, search for External Jump Items must be enabled in SRA settings. Select Allow Search for External Jump Items under Management > Security > Representative Console.

  • FindAvailableEndpointsAsync - This method takes an SRASession object containing basic information about the session, including the SRA user and Jump item. It also takes endpoint search types, an optional search term or criteria that may be null or empty, and an optional limit for most recently used items. The plugin identifies relevant endpoints and returns those as a list of EndpointPackage objects.

Session actions

These methods allow a plugin to handle the various session related requests that can be generated in a SRA session. These only apply to sessions started via External Jump Items created as a result of a call to FindAvailableEndpointsAsync.

  • StartSessionAsync - This method takes an SRASession object containing basic information about the session, including the SRA user and Jump item. It also takes the credential ID selected for injection. This method's purpose is to notify the external system that a session is being initiated, as well as retrieve the credential and all the information necessary for SRA to complete a RDP, SSH, or Web Jump to the endpoint. This information is packaged into a StartSessionDetails object and returned.
  • SessionStartedAsync - This method takes an SRASession object, and an optional history URL (a URL to the tracked session in SRA) and its expiry. The plugin signals the external system that a managed and tracked session has started.
  • SessionCompleteAsync - This method also takes an SRASession object. The plugin signals the external system that a managed and tracked session has started.

Define the entry point

The Program.cs file is the default entry point for the application when it runs. In the ExamplePlugin, this is renamed to PluginRunner.cs, but it is the same file. This is where all the code that supplies the dependency injection engine, supplied by Microsoft.Extensions, with implementations and data is placed.

There are a few primary steps that should take place within your entry point:

Set up and initialize logging

While Microsoft.Extensions.Logging does provide basic logging facilities, you might have other requirements. This can be to remain consistent with your other projects, or because you require more advanced options.

There are many implementations that work with Microsoft.Extensions.Logging for popular logging libraries like Log4Net or Serilog. You can also write your own implementation. You can supply whatever logging provider you like, however it should be done here.

If you do not wish to use any of the out-of-the-box logging facilities from Microsoft.Extensions.Logging, you can remove them by calling:

builder.Logging.ClearProviders();

After the above call you can add your chosen logging providers. Some basic examples are included in the ExamplePlugin.

Once you add your providers, include the following statements that add an instance of the ECMLoggerFactory to the dependency injection engine. These statements ensure that instance is initialized before any further actions. When adding and initializing future types, the statements that create private static logger instances in those classes succeed.

builder.Services.AddSingleton<ECMLoggerFactory>();
builder.Services.BuildServiceProvider().GetService<ECMLoggerFactory>()

You can create a logger instance in the entry point class. Use this statement to add log statements to track progress or handle errors there.

var _logger = ECMLoggerFactory.CreateLogger<Program>();
// Example of usage:
_logger.LogInformation("This is a sample INFO level statement");

Inject configuration and plugin implementation

Since the plugin constructor expects an IOptions, you need to provide your configuration prior to loading the plugin. As with logging, Microsoft.Extensions.Configuration provides some basic out-of-the-box implementations, but you can supply any other that follows the same pattern.

ℹ️

Note

If your plugin configuration contains any sensitive information, it is strongly recommended that you use a configuration provider that can store and read this information securely.

The ExamplePlugin provides a few examples, but the basic pattern will result in a statement like this:

builder.Services.Configure<MyConfigType>(IConfiguration config);

Once you provide a configuration provider, you can add your plugin (IECMPlugin implementation):

builder.Services.AddSingleton<IECMPlugin, MyPlugin>();

Inject configuration and ECM service

Inject the service last, since it expects an IECMPlugin implementation to initialize. Like the plugin, you should add the service configuration in the form of an ECMConfig first and then the service.

You can choose the configuration provider, and then provide an IConfiguration to this example statement:

builder.Services.Configure<ECMConfig>(IConfiguration config);

The ECMServiceFactory provides the service, since its implementation is in a different library distributed separately from the SDK.

Use these statements:

builder.Services.AddSingleton<ECMServiceFactory>();
builder.Services.AddHostedService(sp =>
{
    return builder.Services.BuildServiceProvider()
        .GetService<ECMServiceFactory>()
        .CreateECMService();
});

Build and run the host

The final steps are to build, initialize, and run the IHost.

Use these statements:

var host = builder.Build();
await host.RunAsync();

Configure SRA for the ECM

Create a OAuth API account so the ECM can connect and authenticate to the SRA site.

  1. In /login, go to Management > API Configuration.
  2. Click Add.
  3. Select Enabled.
  4. Name the account.
  5. Use OAuth Client ID and OAuth Client Secret during the OAuth configuration step in Autotask.
  6. Set the following Permissions:
    • Endpoint Credential Manager API - Allow Access
  7. Click Save at the top of the page to create the account.

ℹ️

Note

The ECM Groups feature is only present if enabled when you build your site. If it is not there but should be, contact your site administrator.

Deploy and run as a service

These are examples, however changes may be required due to variations in host systems, how your plugin is constructed, and your organizational requirements.

Run as a Windows Service

  1. Ensure .NET 8 or higher is installed.
  2. Build your project and copy all project output files to a single folder. Ensure that the following files are included:
    • YourOwnPlugin.dll
    • BeyondTrustECMSDK.dll (installed from NuGet)
    • BeyondTrustECMService.dll (provided by BeyondTrust upon request)
    • BeyondTrustECMSharedUtils.dll (provided by BeyondTrust upon request)
    • appsettings.json (or other configuration related files depending on the configuration provider you've chosen)
    • Any other related dependency files
  3. Configure the application.
  4. If your plugin was built on a Windows system, there is an .exe file in addition to the .dll. You can utilize the following PowerShell command to create a service that will execute your plugin:
New-Service -Name "YourOwnPlugin" -BinaryPathName "C:\Path\To\Plugin\YourOwnPlugin.exe" -DisplayName "Company - Your Own Plugin" -StartupType Automatic

ℹ️

Note

More information on the New-Service cmdlet can be found on Microsoft's website.

Run as a Linux System Process

  1. Install .NET 8 on Linux using the install script (dotnet-install.sh): Scripted Install Instructions
  2. Copy all project output files to a single folder. Ensure the following files are included:
    • YourOwnPlugin.dll
    • BeyondTrustECMSDK.dll (installed from NuGet)
    • BeyondTrustECMService.dll (provided by BeyondTrust upon request)
    • BeyondTrustECMSharedUtils.dll (provided by BeyondTrust upon request)
    • appsettings.json (or other configuration related files depending on the configuration provider you've chosen)
    • Any other related dependency files
  3. Configure the application.
  4. In the same folder, run the following command:
dotnet YourOwnPlugin.dll

ℹ️

Note

You might need to specify the dotnet path explicitly.

  1. To stop the process, press Ctrl+C.

Run in a Docker container

  1. Create a C:\temp folder.
  2. Copy dotnet-install.sh you downloaded for Linux in previous section to C:\temp.
  3. Create a C:\temp\ecm folder and copy all project output files, including the appsettings.json, to C:\temp\ecm.
  4. Start your Docker container by running:
docker run -d -v /c/temp:/mnt/temp -e DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 -it ubuntu /bin/bash

This mounts your local temp folder and sets up the necessary environment.1. Run the following commands to update/setup your system and test your integration:

bash
cd /mnt/temp
chmod +x dotnet-install.sh
./dotnet-install.sh
cd ecm
/root/.dotnet/dotnet YourOwnPlugin.dll appsettings.json

ℹ️

Note

This set of commands does not copy the ECM folder to the Linux computer. In a production environment, ensure you manually copy the necessary files.

Troubleshooting

Due to variations in implementation of your plugin, these suggestions may not be exact.

  • Is it running?

    There are many reasons a process may not run, especially when it is a system process or service and not one that you manually started. If it's not running, look for logs generated by your plugin and system logs. Logs may contain information on a failure to start or unexpected exit, such as the System Event Viewer in Windows.

  • Is it configured correctly?

    If the process is running, verify that you provided the correct configuration and that the process can access it. Common errors include forgetting to copy a configuration file (example: appsettings.json), using an inaccessible file due to permissions or network issues, and value typos.

  • Is it connected to your SRA instance?

    A running instance may fail to connect to your SRA instance for a few reasons. To verify connection status, go to your SRA site. In /login, go to Status and view connected ECM Clients. If you do not see your instance in the list:

    • It could be due to misconfiguration in the plugin. Ensure the configured hostname and API Account information are correct. This would be indicated in the logs as a failure to resolve the host, an SSL handshake issue, or an error indicating it failed to authenticate.
    • It could be due to misconfiguration on the SRA side. Ensure that the API account has Endpoint Credential Manager API access, the account is enabled and not locked, and that it contains no Network Restrictions that do not allow access from your host.
  • Is it healthy?

    It is possible for an ECM instance to successfully connect to your SRA site but not receive any requests for credentials or endpoints from that site. If your plugin reports that is supports health checks, the site reaches out to request a health check status. When a plugin reports anything other than a healthy status, the site ceases routing any other requests to that ECM instance until it returns to a healthy state. Your plugin logs useful information to help debug any sort of health check failures. For more information see sections on GetPluginCapabilities and PerformHealthCheckAsync.

  • Is it communicating with my vault?

    How you verify and correct this issue is specific to your implementation, but the questions above apply here as well. Check your plugin logs for useful information.

  • Is it a data issue?

    Perhaps everything is working as it should, but no data is being returned. While your product and implementation dictates how to address this, here is some guidance based on our own implementations and experience. Data issues could be due to:

    • Lack of access: Whether you are retrieving data from the vault as an API account or as individual users, make sure the user can access the data. Perform any additional steps to allow access to that data via the product's APIs.
    • Mismatched user information: Depending on the Security Provider used to authenticate users to your SRA instance, you might see different information about that user in your plugin. For example, an LDAP provider attached to an Active Directory instance will include a user's DistinguishedName from which you can extract their domain. But the same user authenticating via SAML will not have this field populated. It's not uncommon for someone to have different usernames when different authentication mechanisms are used for SRA and your vault (Example: [email protected] and jsmith). If the integration relies on a match, this would be an issue.
    • Mismatched endpoint information: Similar to the above, ensure the information the Jump Item provides in the request to your plugin contains the appropriate values.This helps you match with corresponding systems and accounts in your vault.
      • This would be highlighted by logging in your plugin, however the ECM runtime also logs some of this information as incoming requests are received.
  • What are these "Pong" messages?

    To maintain the socket connection back to the SRA site, a keep-alive message transmits every 10 seconds. The ECM runtime handles this, and it isn't anything you need to handle in your plugin. These requests are not in the plugin code.

Other resources


©2003-2025 BeyondTrust Corporation. All Rights Reserved. Other trademarks identified on this page are owned by their respective owners. BeyondTrust is not a chartered bank or trust company, or depository institution. It is not authorized to accept deposits or trust accounts and is not licensed or regulated by any state or federal banking authority.