Advanced Client setup

Note

This page deals with advanced topics related to the RADKit Client. If you are just getting started, you may want to follow RADKit Client then move on to Introduction to RADKit Client, and come back to this section later.

Enrolling the Client

For some applications such as scripting and automation, it may be useful to authenticate the Client using a certificate instead of SSO. To enroll your Client, simply call the enroll_client() method on an SSO-authenticated Client object (see Starting RADKit Client on Windows/macOS), and when prompted, choose a secure password to protect the private key of your new Client identity certificate:

>>> client.enroll_client()
New private key password: *********
Confirm: *********

Danger

The private key and its passphrase are highly sensitive information. Their usage is strictly restricted to the owner of the keys, and those CANNOT BE SHARED UNDER ANY CIRCUMSTANCES. Sharing those credentials exposes the owner to impersonation attacks. Apply all possible security measures:

  • use a very strong passphrase;

  • never store the passphrase into code;

  • never store the passphrase into a code repository (e.g. Git);

  • use a vault whenever possible.

Sharing your private key or passphrase is akin to sharing your CCO credentials. Do not be careless. Keep your job. Keep your secrets safe.

You can then perform subsequent logins using certificate_login() instead of sso_login() still providing the email address associated with your Cisco account:

>>> certificate_login("myuserid@cisco.com")
Private key password: ***********

[CONNECTED] Client(status='CONNECTED')
-----------------  -----------------------------------------------------------
connected_domains  IQ_CLOUD (myuserid@cisco.com; certificate auth; authenticated )
services           not connected to any service
running_proxies    no local proxy running
-----------------  -----------------------------------------------------------
 HINT:  use grant_service_otp('<service_owner_email>') to authorize provisioning of a RADKit Service

Non-interactive authentication

Once the Client is enrolled, it is possible to pass the private key password in an environment variable so that the certificate_login() command will not interactively ask for the password.

This is done by setting the RADKIT_CLIENT_PRIVATE_KEY_PASSWORD_BASE64 environment variable with the password encoded in Base64, for example (on Linux or macOS):

% export RADKIT_CLIENT_PRIVATE_KEY_PASSWORD_BASE64="$( echo -n 'MyPassW0rd' | base64 )"
% radkit-client
>>> certificate_login("myuserid@cisco.com")
>>>

Danger

Storing a password in an environment variable is inherently insecure and is not recommended in any way, especially if the password unlocks credentials that grant access to a production environment. The Base64 encoding only protects against the most trivial over-the-shoulder password gleaning attacks. It does not provide any actual security. Use this authentication method at your own risk, preferably in a controlled and secure environment.

Renewing the Client Certificate

Client certificates (issued when the Client is enrolled) are renewed automatically by default. Automatic renewal is controlled by cloud_client.automatic_certificate_renewal_enabled. If it is disabled, the owner of the Client is responsible for renewing the certificate before it expires, otherwise the Client must be re-enrolled.

When automatic renewal is disabled and a certificate is within its renewal window at login time, the Client emits a warning indicating how many days remain before expiration and reminding the user to renew it manually. The renewal window is controlled by cloud_client.certificate_renewal_remaining_lifetime (in days, default 15).

To renew the certificate manually, call client.renew_certificate():

>>> certificate_login("myuserid@cisco.com")

11:34:40.001Z WARNING | Client certificate for 'myuserid@cisco.com' expires in 12 day(s). Run client.renew_certificate() to renew it.

>>> client.renew_certificate()

11:34:45.816Z INFO  | Renewing certificate [serial='XXXXXXXXXX']
11:34:52.871Z INFO  | Saving new certificate [serial='YYYYYYYYY']
11:34:52.880Z INFO  | Certificate renewed and saved successfully. Revoking old certificate.
11:34:53.391Z INFO  | Old certificate revoked successfully.

If the login was performed with custom certificate paths (cert_path, key_path and ca_path), the renewed certificate, private key and issuer chain are written back to those same files. Otherwise they are stored in the default identities storage.

Danger

The old certificate is revoked only after the renewed certificate has been safely written to disk. If writing the renewed certificate fails, renew_certificate() raises an error and the old certificate is left intact and valid, so you never end up without a usable certificate.