External sources
The external sources feature enables integration with third-party applications and services. It allows for the delegation of device authentication and/or administrative authentication, such as external secret storage or third-party admin authentication methods.
There are two types of authentication:
Admin Authentication: used by RADKit Service to authenticate RADKit administrators (e.g at the RADKit WebUI logon).
Device Authentication: used by RADKit Service to authenticate to network devices.
The purpose of Admin external sources is to allow for the authentication of RADKit administrators to be delegated to the company credentials management system.
The purposes of Device external sources is to detach the credentials to a device from the main RADKit device definition. This separation allows for the credentials to be stored in
a secure location, such as a secrets management system (Vault, TACACS+ server, …), or
a central place, in the RADKit database in order to minimize the effort of updating all credentials at once.
Warning
Currently, the configuration of external sources is exclusively available through
the Service WebUI and is accessible solely to the superadmin
user role. To manage
external sources, navigate to the External Sources
tab where you can add, edit,
or remove configurations.
Admin authentication
When an administrator is defined on an external source, prefix the admin username with the
external source name and a hash symbol: <name_of_external_source>#<admin_user>
.
As for now only TACACS+ and plugins are capable of admin authentication:
TACACS+
Plugin
Device authentication
Device authentication details are covered in Device Templates.
CyberArk AIM CCP
Note
This section is a work in progress.
CyberArk Conjur
Note
This section is a work in progress.
Static Credentials
Note
This section is a work in progress.
Static credentials is useful when many devices share the same credentials. The device definition can refer to the external source of type Static Credentials, which stores the credentials in an encrypted form in the RADKit database.
When credentials need to be updated, only the Static Credentials definition needs to be updated, and all referring devices will automatically use the new credentials.
The statc credentials can be configured by referencing the external source in the YAML configuration:
terminal:
external_source:
name: <name_of_external_source>
Static credentials external source also allows for secret retrieval, which can be specified in the YAML configuration as follows:
terminal:
password:
external_source: <name_of_external_source>
path: password
username:
external_source: <name_of_external_source>
path: username
HashiCorp Vault
Integrating HashiCorp Vault with RADKit allows you to securely access your secrets.
Here is how you can get started:

Configuration Steps
Base URL: Provide the base URL of your HashiCorp Vault server. This is the primary endpoint for API interactions. Ensure the URL is correct and accessible from your network.
Secret Engine: Select the secret engine type you want to use:
Cubbyhole: Used for storing secrets in a private, per-client space.
KV v1: The first version of HashiCorp Vault’s key-value store.
KV v2: An enhanced version of the key-value store with support for versioning.
Engine Path: Specify the path for the secret engine. This is the location within the Vault where your secrets are stored. Default paths are available based on the selected secret engine:
Cubbyhole: Defaults to /cubbyhole/
KV v1 and KV v2: Defaults to /secret/
Auth Method: Choose the authentication method for accessing Vault:
Token: Use a pre-generated token for authentication. This method is straightforward and requires a token with appropriate permissions.
AppRole: Use an AppRole to authenticate. This method involves providing a Role ID and a Secret ID.
Auth Path: Enter the path for authentication. This path is used to authenticate the client against the Vault server. Default paths are set based on the chosen authentication method:
Token: Defaults to /token/
AppRole: Defaults to /approle/
Token/Role ID/Secret ID:
If using Token authentication, provide the token value.
If using AppRole authentication, provide the Role ID and Secret ID.
Verify TLS Certificate: Check this option if you want to verify the Vault server’s TLS certificate. It’s recommended to enable this in production environments to ensure secure communication.
Use Insecure TLS Algorithms: Enable this option if your Vault server requires support for outdated or insecure TLS algorithms. Use this option with caution.
Note
Ensure that the Vault server is configured with the necessary policies and permissions to allow the RADKit Service to access the required secrets
Usage
To retrieve a specific secret from HashiCorp Vault, reference the external source by name in the YAML configuration, including the secret’s path:
terminal:
password:
external_source: <name_of_external_source>
path: <secret_path/key>
Plugin
This external source type allows the integration of third-party external source implementations. Plugins are added by installing plugin packages that will be visible during the configuration.
Plugin package
Plugin packages are Python packages that uses metadata for plugins through entrypoints.
The plugin package needs to register classes as a entrypoints for radkit_service.external_sources.plugins
group.
Examples:
pyproject.toml
[project.entry-points."radkit_service.external_sources.plugins"]
"My Custom Plugin" = "my_package.my_module:MyClass"
setup.py
from setuptools import setup
setup(
...,
entry_points={
"radkit_service.external_sources.plugins": [
"My Custom Plugin = my_package.my_module:MyClass",
],
},
)
config.cfg
[options.entry_points]
radkit_service.external_sources.plugins =
My Custom Plugin = my_package.my_module:MyClass
Protocol
To fulfill the protocol’s needs, the configured implementation must follow the defined protocol:
- class radkit_service.external_sources.ExternalSource
Bases:
Protocol
External Source Protocol definition.
There are four methods for utilizing external sources:
Generating terminal/netconf/snmp/swagger/http connection parameters:
In this method, within the YAML protocol definitions, the external source is cited in the protocol section, for example:
terminal: external_source: name: <name of referenced external source> params: <additional parameters for external source>
Here, the external source is tasked with constructing the
TerminalConnectionParameters
data structure, triggering the invocation ofcreate_terminal_connection_parameters
.Retrieving secret attributes:
In this method, within the YAML protocol definitions, the external source is mentioned in the attribute definition, for instance:
terminal: password: external_source: <name of referenced external source> path: <secret path>
This indicates that the external source is accountable for procuring the specific secret, and
fetch_secret
will be executed as below:await external_source.fetch_secret(path=<secret path>)
Authenticating users:
In this method external source will be used for authenticating admins for login or authentication remote users for RPC calls. Passed username and password will be passed like this:
await external_source.authenticate_user( username=<username>, password=<password>, )
Authorizing users
In this method external source will be used for authorizing remote user for RPC calls.
Passed username will be passed like this:
await external_source.authorize_user(username=<username>)
Returned authorized user data structure is used downstream to accept or reject specific connection. If
None
is returned, it means that user is not authorized.Note
As for now, we are unable to do direct SSO connections if external source is used for remote user authentication and authorization.
Should a particular external source implementation be incapable of generating connection parameters or retrieving secrets, it ought to return a
NotImplementedError
.Warning
Implementing a cache mechanism might provide some performance improvements, but long TTLs can reduce reactivity for changes. For example, caching authentication results can lead to a situation where a non-authorized user might be authenticated due to the cache.
- async create_terminal_connection_parameters(
- external_source_terminal: ExternalSourceTerminal,
Creates terminal connection parameters out of External Source Terminal definition.
- async create_netconf_connection_parameters(
- external_source_netconf: ExternalSourceNetconf,
Creates netconf connection parameters out of External Source Netconf definition.
- async create_snmp_connection_parameters(
- external_source_snmp: ExternalSourceSnmp,
Creates snmp connection parameters out of External Source SNMP definition.
- async create_swagger_connection_parameters(
- external_source_swagger: ExternalSourceSwagger,
Creates swagger connection parameters out of External Source Swagger definition.
- async create_http_connection_parameters(
- external_source_http: ExternalSourceHttp,
Creates http connection parameters out of External Source HTTP definition.
- async fetch_secret(
- path: str,
Fetch secret for given path.
- async authenticate_user(
- username: str,
- password: str,
Authenticates user by given credentials.
- async authorize_user(
- username: str,
Authorizes user.
Data types
- pydantic model radkit_service.database.models.DbExternalSourceTerminal
Bases:
_NestedModel
- field external_source: DbExternalSourceReference | None = None
- field port: int | TemplateStr = 22
- field connection_method: Literal[ConnectionMethod.SSH, ConnectionMethod.TELNET, ConnectionMethod.SSHPUBKEY, ConnectionMethod.TELNET_NO_AUTH] | TemplateStr [Required]
- Validated by:
_validate_connection_method
- field use_insecure_algorithms: bool | TemplateStr = False
- field jumphost: bool | TemplateStr = False
- field use_tunneling_if_jumphost: bool | TemplateStr = True
- field provisioning_variant: ProvisioningVariant | TemplateStr = ProvisioningVariant.DEFAULT
- field capabilities: frozenset[TerminalCapabilities | TemplateStr] = frozenset({TerminalCapabilities.DOWNLOAD, TerminalCapabilities.EXEC, TerminalCapabilities.INTERACTIVE, TerminalCapabilities.UPLOAD})
- field username: DbExternalSourceSecret | DbExternalSourceValue | None = None
- field password: DbExternalSourceSecret | None = None
- field enable_password: DbExternalSourceSecret | None = None
- field private_key: DbExternalSourceSecret | None = None
- pydantic model radkit_service.database.models.DbExternalSourceNetconf
Bases:
_NestedModel
- field external_source: DbExternalSourceReference | None = None
- field port: int | TemplateStr = 830
- field use_insecure_algorithms: bool | TemplateStr = False
- field username: DbExternalSourceSecret | DbExternalSourceValue | None = None
- field password: DbExternalSourceSecret | None = None
- pydantic model radkit_service.database.models.DbExternalSourceSnmp
Bases:
_NestedModel
- field external_source: DbExternalSourceReference | None = None
- field version: int | TemplateStr [Required]
- Constraints:
ge = 1
le = 2
- field port: int | TemplateStr [Required]
- field community_string: DbExternalSourceSecret | None = None
- pydantic model radkit_service.database.models.DbExternalSourceSwagger
Bases:
_NestedModel
- field external_source: DbExternalSourceReference | None = None
- field port: int | TemplateStr = 443
- field schema_path: TemplateStr | str = ''
- field verify: bool | TemplateStr [Required]
- field use_insecure_algorithms: bool | TemplateStr = False
- field username: DbExternalSourceSecret | DbExternalSourceValue | None = None
- field password: DbExternalSourceSecret | None = None
- pydantic model radkit_service.database.models.DbExternalSourceHttp
Bases:
_NestedModel
- field external_source: DbExternalSourceReference | None = None
- field port: int | TemplateStr [Required]
- field protocol: HTTPProtocol | TemplateStr [Required]
- field verify: bool | TemplateStr [Required]
- field use_insecure_algorithms: bool | TemplateStr = False
- field authentication_extra: TemplateStr | str | None = None
- field username: DbExternalSourceSecret | DbExternalSourceValue | None = None
- field password: DbExternalSourceSecret | None = None
- class radkit_service.external_sources.types.AuthenticatedUser
Bases:
TypedDict
Data structure used to describe authenticated user. Used in webserver session middleware.
- username: str
- email: str
- fullname: str
- description: str
- class radkit_service.external_sources.types.AuthorizedUser
Bases:
TypedDict
Data structure used to describe authorized user. Used in database device backend.
- connection_mode_cloud_active: bool
- connection_mode_direct_active: bool
- connection_mode_direct_sso_active: bool
- class radkit_service.external_sources.types.TerminalConnectionParameters
Bases:
TypedDict
- username: str
- password: str
- port: int
- connection_method: ConnectionMethod | str
- enable_password: str
- enable_set: bool
- use_insecure_algorithms: bool
- private_key: str
- use_tunneling_if_jumphost: bool
- ssh_client_parameters: SSHClientParameters | None
- provisioning_variant: ProvisioningVariant | str
- capabilities: Collection[TerminalCapabilities | str]
- class radkit_service.external_sources.types.NetconfConnectionParameters
Bases:
TypedDict
- username: str
- password: str
- port: int
- use_insecure_algorithms: bool
- class radkit_service.external_sources.types.SwaggerConnectionParameters
Bases:
TypedDict
- username: str
- password: str
- verify: bool
- use_insecure_algorithms: bool
- schema_path: str
- port: int
- class radkit_service.external_sources.types.SNMPConnectionParameters
Bases:
TypedDict
- version: int
- community_string: str
- port: int
- class radkit_service.external_sources.types.HTTPConnectionParameters
Bases:
TypedDict
- username: str
- password: str
- port: int
- protocol: HTTPProtocol | str
- verify: bool
- use_insecure_algorithms: bool
- authentication_extra: str | None
- class radkit_common.types.ConnectionMethod
Bases:
str
,Enum
- SSH = 'SSH'
- SSHPUBKEY = 'SSHPUBKEY'
- TELNET = 'TELNET'
- TELNET_NO_AUTH = 'TELNET_NO_AUTH'
- NETCONF = 'NETCONF'
- class radkit_common.types.TerminalCapabilities
Bases:
str
,Enum
- INTERACTIVE = 'INTERACTIVE'
- EXEC = 'EXEC'
- UPLOAD = 'UPLOAD'
- DOWNLOAD = 'DOWNLOAD'
- class radkit_common.terminal_interaction.provisioning_variants.ProvisioningVariant
Bases:
str
,Enum
- DEFAULT = 'DEFAULT'
- NCS_2000_LF1 = 'LF1'
- class radkit_service.external_sources.types.SSHClientParameters
Bases:
TypedDict
Class stores all of the parameters that controls behavior for SSH protocol.
- keyboard_interactive_auth_requested_cb: KeyboardInteractiveAuthRequestCb | None
- keyboard_interactive_challenge_received_cb: KeyboardInteractiveChallengeReceivedCb | None