Required Python Modules
Python version 2.7.10 is not exactly required, but it is the version being used.
- requests==2.20.0
- python==2.7.10
Variables or Data Needed Before Running
thycoticUsername
- Thycotic admin username that has privileges to add new secrets.
thycoticPw
- Thycotic password for the admin username
serverFQDN
- Thycotic secret server FQDN (Fully Qualified Domain Name)
- ex. mythycotic.foo.com
secretName
- This is the name of the new secret that you are going to create.
- It can be whatever you want.
secretUsername
- The default “password” template has a field for username.
- Although it is not used for any purposes in this template, you can either enter the associated password for reference or just enter
username
password
- This is the new secret password.
- Enter whatever you want the new secret password to be
templateId (not required)
- For this code I have used the default password template ID (2) that is included with the default install of secureServer. If you want to change it, that is up to you, but will have to edit the code to make sure the new data variable in the createSecret method is updated to include all the different fields for the different template.
folderId
- The folder ID where this secret should be saved.
- To find the folder ID:
- Login to your secret server
- Click the folder where you want to have the new secret saved
- Click the edit button
- The folder ID will be displayed in the URL or address bar
- The below example has a FolderId of 5804
-
https://mysecretFQDN.foo.com/secretserver/FolderEdit.aspx?FolderId=5804&returnurl=dashboard.aspx
How to Run and Add New Secret
- Get to a command prompt where you can run python
- Enter
python newThycoticPw.py
- The code will then prompt you for all of the above input or variables.
Code Example Run
prompt# python newThycoticPw.py
Enter Thycotic Username: myusername
Enter Thycotic Password: ************
Enter Thycotic FQDN (ex. mythycotic.foo.com): myThycotic.foo.com
Enter New Secret Name: newSecretfoo
Enter New Secret Username: foo
Enter New Secret Password: ************
Verify New Secret Password: ************
Enter Folder ID where this Secret should be Saved: 5804
The Code
- Save Code as newThycoticPw.py
import requests
import json
import getpass
import traceback
class Secure(object):
#server fully qualified domain name
# Where your thycotic server application is installed
appPath = '/secretserver'
def __init__(self, username, password, serverFQDN):
self.serverFQDN = serverFQDN
self.username = username
self.password = password
url = "https://{}{}/oauth2/token".format(self.serverFQDN, self.appPath)
payload = {'username': self.username,
'password': self.password,
'grant_type': 'password'
}
headers = {
# 'Accept-Encoding': 'gzip,deflate',
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
}
response = requests.request("POST", url, data=payload, headers=headers)
if response.status_code >= 400:
raise Exception('Token ERROR: {}'.format(response.text))
self.token = json.loads(response.text)['access_token']
def createSecret(self, secretName, secretUsername, password, templateId, folderId):
url = "https://{}{}/api/v1/secrets/".format(self.serverFQDN, self.appPath)
headers = {
'authorization': "Bearer {}".format(self.token),
'Accept-Encoding': 'gzip,deflate',
'Accept': 'application/json',
'Content-Type': 'application/json',
}
data = {u'requiresComment': False, u'enableInheritPermissions': True, u'isOutOfSync': False,
u'checkOutEnabled': False, u'allowOwnersUnrestrictedSshCommands': False,
u'checkOutChangePasswordEnabled': False, u'enableInheritSecretPolicy': True,
u'autoChangeEnabled': False, u'sessionRecordingEnabled': False, u'lastHeartBeatStatus': u'Pending',
u'restrictSshCommands': False, u'active': True, u'isDoubleLock': False, u'siteId': 1,
u'folderId': folderId, u'items': [
{u'isNotes': False, u'fieldDescription': u'The URL or location where information is being secured.',
u'isPassword': False, u'isFile': False, u'filename': None, u'fieldName': u'Resource',
u'itemValue': u'', u'fileAttachmentId': None, u'fieldId': 60, u'slug': u'resource'},
{u'isNotes': False, u'fieldDescription': u'The name assocated with the password.', u'isPassword': False,
u'isFile': False, u'filename': None, u'fieldName': u'Username', u'itemValue': secretUsername,
u'fileAttachmentId': None, u'fieldId': 61, u'slug': u'username'},
{u'isNotes': False, u'fieldDescription': u'The password used to access information.',
u'isPassword': True, u'isFile': False, u'filename': None, u'fieldName': u'Password',
u'itemValue': password, u'fileAttachmentId': None, u'fieldId': 7, u'slug': u'password'},
{u'isNotes': True, u'fieldDescription': u'Any comments or additional information for the secret.',
u'isPassword': False, u'isFile': False, u'filename': None, u'fieldName': u'Notes', u'itemValue': u'',
u'fileAttachmentId': None, u'fieldId': 8, u'slug': u'notes'}], u'name': secretName,
u'secretTemplateId': templateId}
response = requests.request("POST", url, headers=headers, data=json.dumps(data))
if response.status_code >= 400:
raise Exception('create Secret ERROR: {}'.format(response.text))
if __name__ == '__main__':
try:
thycoticUsername = raw_input('Enter Thycotic Username: ')
thycoticPw = getpass.getpass('Enter Thycotic Password: ')
serverFQDN = raw_input('Enter Thycotic FQDN (ex. mythycotic.foo.com): ')
doIt = Secure(thycoticUsername, thycoticPw, serverFQDN)
secretName = raw_input('Enter New Secret Name: ')
secretUsername = raw_input('Enter New Secret Username: ')
# Generate new Password
password = getpass.getpass('Enter New Secret Password: ')
vpassword = getpass.getpass('Verify New Secret Password: ')
while password != vpassword:
print('Passwords do not match!')
password = getpass.getpass('Enter New Secret Password: ')
vpassword = getpass.getpass('Verify New Secret Password: ')
templateId = 2
folderId = raw_input('Enter Folder ID where this Secret should be Saved: ')
doIt.createSecret(secretName, secretUsername, password, templateId, folderId)
except:
print(traceback.format_exc())
Where are you getting the fieldId integers from?
Those were pulled probably from a “GET” and I didn’t scrub them out because I am lazy. This code still works to this day and haven’t had any issues. I think it could be removed if you wanted to clean it up. The API ignores them regardless. Let me know other wise.