{ "info": { "author": "Romain Lienard", "author_email": "rlienard@fr.ibm.com", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "Programming Language :: Python :: 3" ], "description": "# ISSS - A Python module for IBM Security Secret Server\n\nThe `isss` module is meant to be an abstract layer on top of the IBM Security Secret Server REST APIs.\n\nIt is **NOT** a full implementation of the REST APIs capabilities. It only provides wrappers for most useful scenarios, additionnal functions will appear from time to time.\n\nAlso, notice that you will use it at your own risk, as *it is not officially supported by IBM*\n\n# Installation & pre-requisites\n\nFrom a terminal, simply issue the following command : \n\n```\n$ pip install isss\n```\n\nAnd that's all ! The library should work as-is. It should be OS independant too, but it's **compatible with Python 3.x only**\n\nYou can verify your installation by copy-pasting this line into a shell : \n\n```\n$ python -c \"import isss; print (isss.version)\"\n```\n\nIt should display your current isss version. If you've got an error complaining about several missing modules, it's probably a system config issue resulting in the old python 2.7 being run by default instead of python 3\n\nTry to issue the same command, but using `python3` instead of `python` to force the use of python 3.x \n\n```\n$ python3 -c \"import isss; print (isss.version)\"\n```\n\n# Current known limitations\n\nMany ! Either because I'm lacking of time or because some REST APIs are simply not available (unlike their SOAP counterpart), you might find that the thing you want to achieve is not possible with the current version of the module. \n\nNon exhaustive list of missing features:\n\n* Create or search secret policies (REST APIs seem not available)\n* Advanced search (pagination, complex queries). Only per-id or global search text is available for most items (users, secrets, groups, folders) and only first 100 items are returned\n* Checkin, checkout\n* Recorded sessions\n* Teams\n* Workflows\n\nThis module is still a work in progress, though.\n\n# Importing the module\n\nBefore using the module, you must import it (who knew?). The `isss` module contains a class named `ISSS` which contains everything you need. \n\n```python\nfrom isss import ISSS\nisss = ISSS(\"https://your.server.demo.com/SecretServer\",\"admin\",\"yourpassword\")\n```\n\n# Stubs\n\nA stub is basically a map of values that you can read, but also edit then push back to secret server to create or update a resource. You'll get a stub (or list of stubs) after a search, a create, or an update.\n\n**Tip** : from an interactive shell, stubs can be pretty-printed to have a clear view of their content: \n\n```python\n>>> u = isss.getUser(3)\n>>> u\n\n>>> print(u)\n- id : 3\n- userName : python\n- displayName : Python App\n- lastLogin : 2019-06-13T12:30:31\n- created : 2019-06-11T09:14:12\n- enabled : True\n- loginFailures : 0\n- emailAddress : None\n- userLcid : 0\n- domainId : -1\n- lastSessionActivity : None\n- isLockedOut : False\n- radiusUserName : None\n- twoFactor : False\n- radiusTwoFactor : False\n- isEmailVerified : False\n- mustVerifyEmail : False\n- verifyEmailSentDate : 0001-01-01T00:00:00\n- passwordLastChanged : 0001-01-01T00:00:00\n- dateOptionId : -1\n- timeOptionId : -1\n- isEmailCopiedFromAD : False\n- organizationUnitId : -1\n- adGuid : None\n- adAccountExpires : 0001-01-01T00:00:00\n- resetSessionStarted : 0001-01-01T00:00:00\n- isApplicationAccount : True\n- oathTwoFactor : False\n- oathVerified : False\n- duoTwoFactor : False\n- fido2TwoFactor : False\n- password : None\n>>> \n\n```\n\n**Tip**: The variables inside a stub are case-insensitive.\n\n```python\nstub[\"username\"] = \"romain\"\nstub[\"userName\"] = \"romain\" #similar to the previous line\n```\n\nOf course, accessing an unknown variable inside the stub will raise an exception.\n\nEach stub will also have a _create()_, an _update()_ and a _delete()_ method, in order to be pushed back to Secret Server. \n\nIt's now time to read the examples below to have a better understanding of the concept.\n\n\n\n# Doing some searches\n\nEach time you'll search for something, you'll get a stub if you pass a numerical id, or a _list of stubs_ if you pass a string query. \n\n\n### Searching secrets\n\n```python\nfor s in isss.getSecret(\"centos root account\"):\n print (s['id'])\n```\n\nor get a specific secret, using a secret ID\n\n```python\nprint (isss.getSecret(2))\n```\n\n\n### Searching users\n\n```python\nfor u in isss.getUser(\"admin\"):\n print (u['id'])\n```\n\n...or get a specific user, using a user ID\n\n```python\nprint (isss.getUser(2))\n```\n\n### Searching groups (and adding users into a group)\n```python\nfor g in isss.getGroup(\"Users\"):\n print (g['id'])\n```\n\n...or get a specific group, using a group ID\n```python\nprint (isss.getGroup(2))\n```\n\n### Searching folders\n\n```python\nfor f in isss.getFolder(\"Windows Systems\"):\n print (f['id'])\n```\n\n...or get a specific folder, using a folder ID\n```python\nprint (isss.getFolder(2))\n```\n\n### Searching templates\n```python\nfor t in isss.getTemplate(\"Unix Account (SSH)\")\n print (\"Template id found : \"), (t[\"id\"])\n```\n\n...or get a specific template, using a template ID\n```python\ntemplate = isss.getTemplate(6007)\n```\n\n# Creating things\n\nTo create something, you'll need an empty stub of this particular something. Once you've got a stub, edit the stub then call its create() method.\n\n### Creating a secret\n\n```python\n#To create a new secret, grab a template id first\nmyid = isss.getTemplates(\"Unix Account (SSH)\")[0][\"id\"]\n\n#Then grab the corresponding secret stub\n#which contains basically all the default values for this template.\nstub = isss.getSecretStub(myid) \n\n#Then edit these values. Be careful, some of them might be mandatory \n#Typically 'name' which is the secret name\n#Developer tip : these fields are case insensitive\n\nstub[\"name\"] = \"python\\\\foobar.demo.com\"\nstub[\"machine\"] = \"foobar.demo.com\"\nstub[\"username\"] = \"root\"\nstub[\"password\"] = stub.generatePassword()\nstub[\"folderId\"] = isss.getFolders(\"Linux\")[0][\"id\"]\nstub[\"enableInheritPermissions\"] = False #important for the next sample\n\n#Display a nice listing of all the available fields and their current value\n#This is useful when playing live with the module\nprint (stub) \n\n#Then finally create the secret, and keep a reference\n#We'll need it very soon\nsecret = stub.create()\n```\n\nPay attention to the use of the generatePassword() method in the previous example. \n\nThis method is only available on stub object, because each secret field can have its own secret policy.\n\nThis is why you also might need to specify the name of the field as a parameter so that the method will generate a valid password for the associated field. \n\nFor convenient reason, default field name is set to `\"password\"`.\n\n```python\n# private key passphrase may require a longer password\nstub[\"Private Key Passphrase\"] = stub.generatePassword(\"Private Key Passphrase\")\n```\n\n### Creating a secret permission\n\nTo create a new permission for a specific secret, you must first grab a secret id to retrieve the corresponding stub.\n\n```python\n#the secret variable come from the previous sample\nstub = isss.getSecretPermissionStub(secret[\"id\"])\nstub[\"userId\"] = 4\nstub[\"secretAccessRoleName\"] = \"View\"\nstub.create()\n```\n\nPossible values for secretAccessRoleName are : \"Owner\", \"View\", \"List\", or \"Edit\"\n\n\n### Creating a folder permission\n\nTo create a new permission for a specific folder, you must first grab a folder id to retrieve the corresponding stub.\n\n```python\nstub = isss.getFolderPermissionStub(isss.getFolder(\"Windows\")[0][\"id\"])\nstub[\"userId\"] = 4\nstub[\"folderAccessRoleName\"] = \"View\"\nstub.create()\n```\n\nPossible values for folderAccessRoleName are : \"Owner\", \"View\", \"List\", or \"Edit\"\n\n\n### Creating a user\n\nTo create a new user, it's very similar, yet simpler :\n\n```python\nstub = isss.getUserStub()\nstub[\"username\"] = \"lucifer\"\nstub[\"displayname\"] = \"Lucifer Morningstar\"\nstub[\"password\"] = \"Passw0rd\"\nstub.create()\n```\n\n### Creating a group\n\nYou should now be familiar with the concept...\n\n```python\nstub = isss.getGroupStub()\nstub[\"name\"] = \"awesome people\"\nmygroup = stub.create() #keep a reference to the newly created group\n```\n\nAs seen before, once your group is created you can store the result into a variable so you can start adding users\n\n```python\nmygroup.add(\"admin\")\n```\n\nCaution, _add()_ is expecting **a numerical userId** or **a username**. _Not_ a search query !\n\n# Updating things\n\nUpdate works exactly like create, except your stub has already been created, so instead of calling create() you will call... well... update() \n\n### Updating a user\n\n```python\nu = isss.getUser(4)\nu[\"password\"] = \"new password\"\nu.update()\n```\n\n### Updating a secret\n\n```python\ns = isss.getSecret(12)\ns[\"name\"] += \" (updated)\"\ns.update()\n```\n\n### Updating a group\n\nGroup can be updated like any regular stub, but they also have 3 additionals methods.\n\nA method to add a user into the group:\n\n```python\nisss.getGroup(2).add(\"admin\") #using a search query - must return only 1 result\nisss.getGroup(2).add(2) #or a userid\nisss.getGroup(2).add(\"admin\").add(\"romain\") #tip: you can chain methods\n```\n\nA method to remove a user from the group:\n\n```python\nisss.getGroup(2).remove(\"admin\")\nisss.getGroup(2).remove(2) \nisss.getGroup(2).remove(\"admin\").remove(\"romain\")\n```\n\nAnd a method to list current users in the group:\n\n```python\nfor user in isss.getGroup(2).getUsers():\n\tprint user[\"id\"]\n```\n\nNote : for performance reasons, the `getUsers()` method returns a list of IDs and usernames, **not a list of stubs**.\n\n# Deleting things\n\nWhile many things in Secret Server are never really deleted (we should rather say _disabled_), you can delete object from the server by calling the delete() function on the corresponding stub object\n\n```python\n#delete an existing stub\nmyUser.delete()\nmyGroup.delete()\n\n#search & delete\nisss.getSecret(\"foobar\")[0].delete()\n```\n\n# Experimental APIs\n\nFor some reasons, Scripts APIs don't seem to be available as REST APIs, although they are available as SOAP APIs. For the sake of simplicity (I didn't want to mess with SOAP), the current implementation scraps the Web UI hence is likely to be broken at some point if you are not using the good version of Secret Server (tested on 10.6.000027 only)\n\nTo enable them, you'll need to add `True` to the ISSS constructor : \n\n```python\nfrom isss import ISSS\nisss = ISSS(\n\t\"https://your.server.demo.com/SecretServer\",\n\t\"admin\",\n\t\"yourpassword\", \n\tTrue)\n```\n\n### Get all scripts metadata (PowerShell, SSH, SQL)\n\nIt's very easy to retrieve the list of available scripts. \n\n```python\n#This function only returns script names and IDs\n#Not the actual scripts content\nscripts = isss.getScriptList()\n\n#Iterate over scripts, and grab & update their content\nfor script in scripts:\n if script.name == 'Test SSH':\n script = isss.getScript(script) # get the content\n script.content += \"\\n#automatically added by python\"\n script.update()\n``` \n\nOf course if you know the id of a script, you can still grab it directly\n\n```python\nscript = isss.getScript(8)\nscript.content += \"\\n#automatically addedd by python\"\nscript.update()\n```\n\nIt worth noting that these scripts are not stub objects, like we have seen before.\n\n### Scripts FileWatcher\n\nOK there is a real need behind the crappy Script API that you've just discovered. I'm not expecting anyone to use it (especially since this API might stop working at some point), but if like me you are tired to edit your Heartbeat or Password Changer scripts from the web UI, you might be interested by this filewatcher command which depends on it.\n\nFrom your shell, simply issue the following command : \n\n```\n$ isss-fw https://server/SecretServer admin password directorypath\n```\n\nAnd it will start the filewatcher on the specified `directorypath` (which should be empty - the program will prompt you to delete its content if it's not)\n\nIf the directory doesn't exist, it will be created, and scripts will be automatically downloaded into it. Then any change to one of these files will be detected by the filewatcher and sent back to ISSS.\n\n**Be careful**, it doesn't work with vim or any editor which are using temporary files. I'm using [brackets.io](http://brackets.io \"brackets.io\"), which works pretty well for me.\n\nAlso, you will quickly discover that (for now at least) you can't pass the current directory \".\" as the path parameter, so you will need to start the command from outside the directory you want to use. \n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://www.ibm.com/marketplace/secret-server", "keywords": "isss,ibm,thycotic,secret,server", "license": "", "maintainer": "", "maintainer_email": "", "name": "isss", "package_url": "https://pypi.org/project/isss/", "platform": "", "project_url": "https://pypi.org/project/isss/", "project_urls": { "Homepage": "https://www.ibm.com/marketplace/secret-server" }, "release_url": "https://pypi.org/project/isss/1.0.2/", "requires_dist": null, "requires_python": "", "summary": "A unofficial library which provides wrappers around IBM Security Secret Server REST APIs. Also compatible with Thycotic Secret Server", "version": "1.0.2" }, "last_serial": 5578872, "releases": { "1.0": [ { "comment_text": "", "digests": { "md5": "8200bed0df230a52c0db840108144489", "sha256": "416443bc89852db0cff2388813b7c9c2dbcee5bf28de1bfe5f0efd06e0447532" }, "downloads": -1, "filename": "isss-1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "8200bed0df230a52c0db840108144489", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 17523, "upload_time": "2019-07-12T12:05:12", "url": "https://files.pythonhosted.org/packages/5b/3c/ce5d3cd873a2888cc0dd04e5684482fac45dd386c9a5c3fc87312bb834ca/isss-1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "bcd7c5f8ae623ff2d80e37555f97188d", "sha256": "374e2f45293a4fdb012edc72ddd359b50bae9f9319c461b4fd65ac6f243b03cd" }, "downloads": -1, "filename": "isss-1.0.tar.gz", "has_sig": false, "md5_digest": "bcd7c5f8ae623ff2d80e37555f97188d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18046, "upload_time": "2019-07-12T12:05:14", "url": "https://files.pythonhosted.org/packages/0a/32/4eb62876f79cee70272fd0446c32de032e90a0b7e6899b25c36fff5bd9b0/isss-1.0.tar.gz" } ], "1.0.2": [ { "comment_text": "", "digests": { "md5": "a95b1ea585225d7bb849d132cff44ed0", "sha256": "6d16663ebc394fb66423766b68ab0e9988efb2b34d763c74d18ba01995e6ceb6" }, "downloads": -1, "filename": "isss-1.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "a95b1ea585225d7bb849d132cff44ed0", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 18430, "upload_time": "2019-07-24T17:55:55", "url": "https://files.pythonhosted.org/packages/70/8b/ed1101b3eeb17243f59e0e02a361f87102f718e70e9126c5eb82de039b75/isss-1.0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2a3fdb0caed8fe516794c62f4d2f4b70", "sha256": "0024588287895d2e83c3829d684947c1310ac60f7449f3862563519db7bb15a2" }, "downloads": -1, "filename": "isss-1.0.2.tar.gz", "has_sig": false, "md5_digest": "2a3fdb0caed8fe516794c62f4d2f4b70", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18591, "upload_time": "2019-07-24T17:55:58", "url": "https://files.pythonhosted.org/packages/b8/20/166d2e23094e509c163716eaf006bdefacfc8349a789cdbb8233c8be070b/isss-1.0.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "a95b1ea585225d7bb849d132cff44ed0", "sha256": "6d16663ebc394fb66423766b68ab0e9988efb2b34d763c74d18ba01995e6ceb6" }, "downloads": -1, "filename": "isss-1.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "a95b1ea585225d7bb849d132cff44ed0", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 18430, "upload_time": "2019-07-24T17:55:55", "url": "https://files.pythonhosted.org/packages/70/8b/ed1101b3eeb17243f59e0e02a361f87102f718e70e9126c5eb82de039b75/isss-1.0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2a3fdb0caed8fe516794c62f4d2f4b70", "sha256": "0024588287895d2e83c3829d684947c1310ac60f7449f3862563519db7bb15a2" }, "downloads": -1, "filename": "isss-1.0.2.tar.gz", "has_sig": false, "md5_digest": "2a3fdb0caed8fe516794c62f4d2f4b70", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18591, "upload_time": "2019-07-24T17:55:58", "url": "https://files.pythonhosted.org/packages/b8/20/166d2e23094e509c163716eaf006bdefacfc8349a789cdbb8233c8be070b/isss-1.0.2.tar.gz" } ] }