Python for CPM
Project description
Python4CPM
A simple and secure way of using python scripts with CyberArk CPM/SRS password rotations.
How it works
This module leverages the Credential Management .NET SDK from CyberArk to securely offload a password rotation logic into Python.
All objects are collected from the SDK and sent as environment context to be picked up by the python4cpm module during the subprocess execution of python. All secrets of such environment are protected and encrypted by Data Protection API (DPAPI), until they are explicitely retrieved in your python script runtime, invoking the Secret.get() method. Finally, python controls the termination signal sent back to the SDK, which is consequently used as the return code to CPM/SRS. Such as a successful or failed (recoverable or not) result of the requested action.
This platform allows you to duplicate it multiple times, simply changing its settings (with regular day two operations from Privilege Cloud/PVWA) to point to different venvs and/or python scripts.
Installation
Preparing Python
- Install Python along CPM or the SRS Connector Management Agent.
- Python must be installed for all users. Follow the custom install steps from the installation wizard to check the checkbox.
- Create a venv in the server, by running
py -m venv c:\venv. If desired, use a custom location and adjust any future references. - Install
python4cpmin your venv:- If your CPM can connect to the internet, install with
c:\venv\Scripts\pip.exe install python4cpm. - If your CPM cannot connect to the internet:
- Download the latest
python4cpm-*.whlfile from the pypi project files. - Copy the file to the server into a temporary directory called
python4cpm-wheel. - From the parent directory of
python4cpm-wheelrunc:\venv\Scripts\pip.exe install --no-index --find-links=.\python4cpm-wheel python4cpm.
- Download the latest
- If your CPM can connect to the internet, install with
Importing the platform
If you are using CPM (SaaS or Self-Hosted):
- Download the latest Credential Management .NET SDK and place its content in the bin folder of CPM (
C:\Program Files (x86)\CyberArk\Password Manager\bin). The files for this may already be present. - Download the
python4cpm-platform-*.zipasset from the latest release. - Import the platform zip file into Privilege Cloud/PVWA
(Administration -> Platform Management -> Import platform). - Craft your python script and place it within a folder in CPM (e.g.,
C:\python4cpm-scripts). - Duplicate the imported platform in Privilege Cloud/PVWA
(Administration -> Platform Management -> Application -> Python for CPM)and name it after your application (e.g., My App). - Edit the duplicated platform and specify the path of your script, under
Target Account Platform -> Automatic Platform Management -> Additional Policy Settings -> Parameters -> PythonScriptPath -> Value(e.g.,C:\python4cpm-scripts\myapp.py). - Also update
Target Account Platform -> Automatic Platform Management -> Additional Policy Settings -> Parameters -> PythonExePath -> Valuewith the custom path for the venv'spython.exefile (e.g.,c:\venv\Scripts\python.exe). - If you want to disable logging, update
Target Account Platform -> Automatic Platform Management -> Additional Policy Settings -> Parameters -> PythonLogging -> Valuetono. - If you want to change the logging level to
debug, updateTarget Account Platform -> Automatic Platform Management -> Additional Policy Settings -> Parameters -> PythonLoggingLevel -> Valuetodebug. - For new applications repeat steps from 4 to 9.
If you are using SRS (SaaS only):
- Download the
python4cpm-platform-*.zipasset from the latest release. - Import the platform zip file into Privilege Cloud
(Administration -> Platform Management -> Import platform). - Craft your python script and place it within a folder in the Cloud Connector (where the SRS Management Agent runs) (e.g.,
C:\python4cpm-scripts). - Duplicate the imported platform in Privilege Cloud/PVWA
(Administration -> Platform Management -> Application -> Python for CPM)and name it after your application (e.g., My App). - Edit the duplicated platform and specify the path of your script, under
Plugin Settings -> Additional Parameters -> PythonScriptPath(e.g.,C:\python4cpm-scripts\myapp.py). - Also update
Plugin Settings -> Additional Parameters -> PythonExePathwith the custom path for the venv'spython.exefile (e.g.,c:\venv\Scripts\python.exe). - If you want to disable logging, update
Plugin Settings -> Additional Parameters -> PythonLoggingtono. - If you want to change the logging level to
debug, updatePlugin Settings -> Additional Parameters -> PythonLoggingLevel -> Valuetodebug. - For new applications repeat steps from 3 to 8.
Python Script
from python4cpm import Python4CPMHandler
class MyRotator(Python4CPMHandler):
"""
These are the usable properties and methods from Python4CPMHandler:
self.args.action
# action requested from CPM/SRS
## Target Account
self.target_account.username
# address from account
self.target_account.address
# address from account
self.target_account.port
# port from account
self.target_account.password.get()
# get plaintext str from password object
## Logon Account
self.logon_account.username
self.logon_account.password.get()
## Reconcile Account
self.reconcile_account.username
self.reconcile_account.password.get()
## Logging
self.logger.critical("this is critical message")
self.logger.error("this is an error message")
self.logger.warning("this is a warning message")
self.logger.info("this is an info message")
self.logger.debug("this is a debug message")
# The logging level comes from PythonLoggingLevel (platform parameters) (default is error)
=============================
REQUIRED TERMINATION SIGNALS
=============================
Terminate signals -> MUST use one of the following three signals to terminate the script:
self.close_success()
# terminate and provide CPM/SRS with a success state
self.close_fail()
# terminate and provide CPM/SRS with a failed recoverable state
self.close_fail(unrecoverable=True)
# terminate and provide CPM/SRS with a failed unrecoverable state
When calling a signal sys.exit is invoked and the script is terminated.
If no signal is called, and the script finishes without any exception,
it will behave like p4cpm.close_fail(unrecoverable=True) and log an error message.
=============================
REQUIRED METHODS
=============================
verify(), logon(), change(), prereconcile(), reconcile()
"""
def verify(self):
# TODO: use account objects for your logic
self.close_success()
def logon(self):
# TODO: use account objects for your logic
self.close_success()
def change(self):
# TODO: use account objects for your logic
self.close_success()
def prereconcile(self):
# TODO: use account objects for your logic
self.close_success()
def reconcile(self):
# TODO: use account objects for your logic
self.close_success()
if __name__ == "__main__":
MyRotator().run() # initializes the class and calls the action that was requested from CPM/SRS.
(*) More realistic examples can be found here.
When doing verify, change or reconcile from Privilege Cloud/PVWA:
- Verify -> the sciprt will be executed once running the
MyRotator.verify()method. - Change -> the sciprt will be executed twice, running first the
MyRotator.logon()method and secondly theMyRotator.change()method.- If both actions are not terminated with
self.close_success()and the scripts terminates without any exception, CPM/SRS will see this as aself.close_fail(unrecoverable=True).
- If both actions are not terminated with
- Reconcile -> the sciprt will be executed twice, running first the
MyRotator.prereconcile()method and secondly theMyRotator.reconcile()method.- If both actions are not terminated with
self.close_success()and the scripts terminates without any exception, CPM/SRS will see this as aself.close_fail(unrecoverable=True).
- If both actions are not terminated with
- When calling
MyRotator.verify(),MyRotator.logon()orMyRotator.prereconcile():self.target_account.new_passwordwill always returnNone. - If a logon account is not linked,
self.logon_accountwill returnNone. - If a reconcile account is not linked,
self.reconcile_accountwill returnNone. - The python
Loggerplaces its logs in theLogs/ThirdPartydirectory. The filename will be based on the name of the subclass created (e.g.,MyRotator).
Installing dependencies in python venv
As with any python venv, you can install dependencies in your venv.
- If your CPM can connect to the internet:
- You can use regular pip install commands (e.g.,
c:\venv\Scripts\pip.exe install requests).
- You can use regular pip install commands (e.g.,
- If your CPM cannot connect to the internet:
- You can download packages for an offline install. More info here.
Dev Helper:
For dev purposes, NETHelper is a companion helper to test your scripts without CPM/SRS. It simplifies the instantiation of the Python4CPM or Python4CPMHandler objects by simulating how the plugin creates the environment context for the python module.
Note: As CPM and the SRS management agent run in Windows, the plugin was built to encrypt secrets using DPAPI (a windows only library). For dev purposes in Linux/Mac dev workstations, those secrets put in the environment context by NETHelper will be in plaintext. In windows dev workstations, NETHelper encrypts the secrets as the .NET plugin does. This is informational only, the module will use its encryption/decryption capabilities automatically based on the platform it is running on and you do not have to do anything specific to enable it.
Example:
Set your arguments and secrets:
from python4cpm import NETHelper, Python4CPM, Python4CPMHandler
from getpass import getpass
# Get secrets for your password, logon account password, reconcile account password and new password
# You may set to None any argument that does not apply or simply leaving it to its default None value.
target_password = getpass("password: ") # password from account
logon_password = getpass("logon_password: ") # password from linked logon account
reconcile_password = getpass("reconcile_password: ") # password from linked reconcile account
target_new_password = getpass("new_password: ") # new password for the rotation
NETHelper.set(
action=Python4CPM.ACTION_CHANGE, # use actions from Python4CPM.ACTION_*
target_username="jdoe", # -> will fall under MyRotator.target_account.username
target_address="myapp.corp.local", # -> will fall under MyRotator.target_account.address
target_port="8443", # -> will fall under MyRotator.target_account.port
logon_username="ldoe", # -> will fall under MyRotator.logon_account.username
reconcile_username="rdoe", # -> will fall under MyRotator.reconcile_account.username
logging_level="debug", # "critical", "error", "warning", "info" or "debug"
target_password=target_password, # -> will fall under MyRotator.target_account.password.get()
logon_password=logon_password, # -> will fall under MyRotator.logon_account.password.get()
reconcile_password=reconcile_password, # -> will fall under MyRotator.reconcile_account.password.get()
target_new_password=target_new_password # -> will fall under MyRotator.target_account.new_password.get()
)
class MyRotator(Python4CPMHandler):
def verify(self):
# TODO: Add your logic here
self.close_success()
def logon(self):
# TODO: Add your logic here
self.close_success()
def change(self):
# TODO: Add your logic here
self.close_success()
def prereconcile(self):
# TODO: Add your logic here
self.close_success()
def reconcile(self):
# TODO: Add your logic here
self.close_success()
MyRotator().run()
Remember for your final script:
- Remove the import of
NETHelper. - Remove the
NETHelper.set()call. - Remove any secrets prompting or interactive interruptions.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file python4cpm-1.1.3.tar.gz.
File metadata
- Download URL: python4cpm-1.1.3.tar.gz
- Upload date:
- Size: 13.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8918c7a91083b95174417e0220013249459d136ad61f720f7860d5414cb2a20a
|
|
| MD5 |
f22f42aff86e246d4d4bfec763c6fca8
|
|
| BLAKE2b-256 |
3351973e2062140114140978bfd24353b9bd7c7835eeed6d199690cfe707967e
|
Provenance
The following attestation bundles were made for python4cpm-1.1.3.tar.gz:
Publisher:
release-pypi.yml on gonatienza/python4cpm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
python4cpm-1.1.3.tar.gz -
Subject digest:
8918c7a91083b95174417e0220013249459d136ad61f720f7860d5414cb2a20a - Sigstore transparency entry: 1078543042
- Sigstore integration time:
-
Permalink:
gonatienza/python4cpm@bcaa9a5a7feee11f9c0f0fa4bc7d5b794f03351a -
Branch / Tag:
refs/heads/main - Owner: https://github.com/gonatienza
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-pypi.yml@bcaa9a5a7feee11f9c0f0fa4bc7d5b794f03351a -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file python4cpm-1.1.3-py3-none-any.whl.
File metadata
- Download URL: python4cpm-1.1.3-py3-none-any.whl
- Upload date:
- Size: 11.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a2b0b3b222fbc2b2ac40f2f02a548202584c1ec4ed7c1e4100b38cacd3ed501a
|
|
| MD5 |
766525d1fe519ac8be510b783369d57b
|
|
| BLAKE2b-256 |
d747846a24a3f3bc0c692864fd0b3e52803aa1ff68d78d6d6855a67911ed5d3f
|
Provenance
The following attestation bundles were made for python4cpm-1.1.3-py3-none-any.whl:
Publisher:
release-pypi.yml on gonatienza/python4cpm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
python4cpm-1.1.3-py3-none-any.whl -
Subject digest:
a2b0b3b222fbc2b2ac40f2f02a548202584c1ec4ed7c1e4100b38cacd3ed501a - Sigstore transparency entry: 1078543068
- Sigstore integration time:
-
Permalink:
gonatienza/python4cpm@bcaa9a5a7feee11f9c0f0fa4bc7d5b794f03351a -
Branch / Tag:
refs/heads/main - Owner: https://github.com/gonatienza
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-pypi.yml@bcaa9a5a7feee11f9c0f0fa4bc7d5b794f03351a -
Trigger Event:
workflow_dispatch
-
Statement type: