{ "info": { "author": "@bincyber", "author_email": "", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Console", "Intended Audience :: Developers", "Intended Audience :: System Administrators", "License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)", "Natural Language :: English", "Operating System :: MacOS", "Operating System :: POSIX", "Operating System :: Unix", "Programming Language :: Python", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Security", "Topic :: Security :: Cryptography", "Topic :: System :: Systems Administration", "Topic :: Utilities" ], "description": "# pkictl\n\n[![License](https://img.shields.io/badge/License-MPL-blue.svg)](https://www.gnu.org/licenses/agpl-3.0.en.html)\n[![Python](https://img.shields.io/badge/Python-3.6+-blue.svg)](#)\n[![Version](https://img.shields.io/badge/Version-0.2.1-green.svg)](#)\n[![Docker](https://images.microbadger.com/badges/image/bincyber/pkictl.svg)](https://microbadger.com/images/bincyber/pkictl)\n[![Coverage Status](https://coveralls.io/repos/github/bincyber/pkictl/badge.svg?branch=master)](https://coveralls.io/github/bincyber/pkictl?branch=master)\n[![CircleCI](https://circleci.com/gh/bincyber/pkictl.svg?style=svg)](https://circleci.com/gh/bincyber/pkictl)\n\n\n_pkictl_ is a CLI tool for declaratively configuring and provisioning PKI secrets in HashiCorp Vault. Root and Intermediate Certificate Authorities (CAs) along with their associated roles and policies can be defined and created from a YAML file. It simplifies automating the provisioning of an internal PKI using Vault and strives to achieve idempotency.\n\n_pkictl_ is inspired by [_kubectl_](https://kubernetes.io/docs/reference/kubectl/overview/).\n\n\n## How It Works\n\n_pkictl_ uses the Vault HTTP API to mount [PKI secrets engines](https://www.vaultproject.io/docs/secrets/pki/index.html) for Root and Intermediate CAs. Intermediate CAs can be signed by a Root CA or other Intermediate CAs. Roles and Policies can be defined in the YAML file for Intermediate CAs.\n\nThe [Key/Value secrets engine](https://www.vaultproject.io/docs/secrets/kv/index.html) is also used to store the private keys of Intermediate CAs that are configured for export (ie. `spec.type: exported`).\n\n\n## Installation\n\n_pkictl_ can be installed via pip:\n\n\t$ pip install pkictl\n\n\n### Compatibility\n\n_pkictl_ has been tested against versions 0.10.X, 0.11.X, and 1.0.X of Vault.\n\n## Usage\n\n $ pkictl --help\n\n declaratively configure PKI secrets in Hashicorp Vault\n\n optional arguments:\n -h, --help show this help message and exit\n -d, --debug enable debug output\n -v, --version show program's version number and exit\n\n subcommands:\n\n init Initializes the Hashicorp Vault server\n apply Creates PKI secrets from a YAML file\n\n\n### Prerequisites\n\nIf you're unfamiliar with Vault's PKI secrets, read this guide: [Build Your Own Certificate Authority (CA)](https://learn.hashicorp.com/vault/secrets-management/sm-pki-engine)\n\n_pkictl_ requires an unsealed Hashicorp Vault server and an authentication token with privileges to:\n* mount PKI and KV secrets engines\n* read and write PKI secrets\n* write KV secrets\n\n\n### Initializing the Vault server\n\nInitialize a new Vault server and unseal it:\n\n $ pkictl init -u https://localhost:8200\n\nThe Vault server will be initialized with 5 key shares and a key threshold of 3.\n* the root token is saved in `.vault-token`\n* the master keys shares are saved in `vault.log`\n\nInitializing and unsealing the Vault server this way is only provided as a convenience for development/testing and is highly discouraged.\n\n\n### Declaratively provisioning PKI secrets\n\nA YAML manifest file is used to define Root and Intermediate CAs, Key/Value engines, roles and policies.\n\nCreate a [manifest file](docs/examples/manifest.yaml):\n\n ---\n kind: RootCA\n metadata:\n name: demo-root-ca\n description: pkictl demo Root CA\n spec:\n key_type: ec\n key_bits: 384\n ttl: 17532h\n exclude_cn_from_sans: true\n subject:\n common_name: Demo Root CA\n organization: pkictl\n ou: README Demo\n country: US\n locality: San Francisco\n province: California\n ---\n kind: IntermediateCA\n metadata:\n name: demo-intermediate-ca\n description: pkictl demo Intermediate CA\n issuer: demo-root-ca\n kv_backend: demo-kv-engine\n spec:\n type: exported\n key_type: rsa\n key_bits: 4096\n ttl: 8766h\n subject:\n common_name: Demo Intermediate CA\n organization: pkictl\n ou: README Demo\n country: US\n locality: San Francisco\n province: California\n roles:\n - name: server\n config:\n max_ttl: 8766h\n ttl: 8766h\n allow_subdomains: true\n allowed_domains:\n - demo.pkictl.com\n client_flag: false\n server_flag: true\n - name: client\n config:\n max_ttl: 336h\n ttl: 336h\n allow_any_name: true\n client_flag: true\n server_flag: false\n policies:\n - name: demo-intermediate-ca-pkey\n policy: |\n path \"demo-kv-engine\" {\n capabilities = [\"list\"]\n }\n path \"demo-kv-engine/demo-intermediate-ca\" {\n capabilities = [\"read\"]\n }\n - name: demo-intermediate-ca-server\n policy: |\n path \"demo-intermediate-ca/issue/server\" {\n capabilities = [\"read\", \"update\"]\n }\n path \"demo-intermediate-ca/sign/server\" {\n capabilities = [\"read\", \"update\"]\n }\n - name: demo-intermediate-ca-client\n policy: |\n path \"demo-intermediate-ca/issue/client\" {\n capabilities = [\"read\", \"update\"]\n }\n path \"demo-intermediate-ca/sign/client\" {\n capabilities = [\"read\", \"update\"]\n }\n ---\n kind: KV\n metadata:\n name: demo-kv-engine\n description: pkictl demo KV v1 engine\n spec:\n options:\n version: 1\n\nThe above example will create:\n- an ECDSA-based [Root](https://www.vaultproject.io/api/secret/pki/index.html#generate-root) CA with a TTL of 2 years\n- a RSA-based [Intermediate](https://www.vaultproject.io/api/secret/pki/index.html#generate-intermediate) CA with a TTL of 1 year signed by the Root CA\n- a [Role](https://www.vaultproject.io/api/secret/pki/index.html#create-update-role) named `server` permitting the Intermediate CA to issue or sign TLS server certificates for any subdomains on demo.pkictl.com\n- a [Role](https://www.vaultproject.io/api/secret/pki/index.html#create-update-role) named `client` permitting the Intermediate CA to issue or sign TLS client certificates\n- a [Policy](https://www.vaultproject.io/docs/concepts/policies.html) mapped to the `server` role\n- a [Policy](https://www.vaultproject.io/docs/concepts/policies.html) mapped to the `client` role\n- a [Key/Value](https://www.vaultproject.io/api/secret/kv/kv-v1.html) engine to store the exported private key of the Intermediate CA\n- a [Policy](https://www.vaultproject.io/docs/concepts/policies.html) permitting retrieval of the exported private key from the KV engine\n\nCreate PKI secrets from the YAML manifest file:\n\n $ pkictl apply -u https://localhost:8200 -f manifest.yaml\n\n [*] pkictl - the Vault server has been initialized and is not sealed\n [*] pkictl - Enabled KV backend: demo-kv-engine\n [*] pkictl - Enabled PKI backend: demo-root-ca\n [*] pkictl - Generated Root CA: demo-root-ca\n [*] pkictl - Enabled PKI backend: demo-intermediate-ca\n [*] pkictl - Created intermediate CA: demo-intermediate-ca\n [*] pkictl - Signed intermediate CA 'demo-intermediate-ca' with issuing CA: demo-root-ca\n [*] pkictl - Set signed certificate for intermediate CA: demo-intermediate-ca\n [*] pkictl - Configured URLs for CA: demo-intermediate-ca\n [*] pkictl - Set CRL configuration for CA: demo-intermediate-ca\n [*] pkictl - Stored private key for 'demo-intermediate-ca' in KV backend: demo-kv-engine\n [*] pkictl - Configured role 'server' for intermediate CA: demo-intermediate-ca\n [*] pkictl - Configured role 'client' for intermediate CA: demo-intermediate-ca\n [*] pkictl - Configured policy 'demo-intermediate-ca-pkey' for intermediate CA: demo-intermediate-ca\n [*] pkictl - Configured policy 'demo-intermediate-ca-server' for intermediate CA: demo-intermediate-ca\n [*] pkictl - Configured policy 'demo-intermediate-ca-client' for intermediate CA: demo-intermediate-ca\n\nObtain a Vault token attached to the `demo-intermediate-ca-server` Policy:\n\n $ VAULT_TOKEN=$(vault token create -policy=demo-intermediate-ca-client -ttl=1h -format json | jq -r .auth.client_token)\n\nUse this token to obtain a TLS server certificate and private key for web.demo.pkictl.com from the Intermediate CA:\n\n $ vault write demo-intermediate-ca/issue/server common_name=web.demo.pkictl.com ttl=2160h\n\nAlternatively, you can generate a certificate signing request (CSR) and private key locally and have the CSR signed by the Intermediate CA:\n\n $ openssl req -batch -nodes -sha256 -new -newkey rsa:2048 \\\n -keyout web.demo.pkictl.com.key -out web.demo.pkictl.com.csr -subj '/CN=web.demo.pkictl.com/'\n\n $ vault write demo-intermediate-ca/sign/server csr=@web.demo.pkictl.com.csr ttl=2160h\n\nVault will return the signed TLS server certificate along with the full chain (the certificates for the Root and Intermediate CA).\n\nObtain a Vault token attached to the `demo-intermediate-ca-client` Policy:\n\n $ VAULT_TOKEN=$(vault token create -policy=demo-intermediate-ca-client -ttl=1h -format json | jq -r .auth.client_token)\n\nUse this token to obtain a TLS client certificate and private key from the Intermediate CA:\n\n $ vault write demo-intermediate-ca/issue/client common_name=\"example@demo.pkictl.com\" ttl=24h\n\nSince `spec.type: exported`, the private key of this CA has been saved in the KV engine `demo-kv-engine`. A Vault token attached to the `demo-intermediate-ca-pkey` Policy is required to retrieve it:\n\n $ VAULT_TOKEN=$(vault token create -policy=demo-intermediate-ca-pkey -ttl=1m -format json | jq -r .auth.client_token)\n $ vault kv get -version=1 demo-kv-engine/demo-intermediate-ca\n\n### Documentation\n\nFor documentation and additional examples, see the [docs](https://github.com/bincyber/pkictl/tree/master/docs) directory.\n\n### Testing\n\n[nose2](http://nose2.readthedocs.io/en/latest/) is used for testing. Tests are located in `pkictl/tests`.\n\nTo run the unit tests:\n\n $ make test\n\nEnd to end tests requires Vault running locally. To build and run the Vault container:\n\n $ make build-vault-container\n $ make run-vault-container\n\nRun the end-to-end tests:\n\n $ make e2e-test\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": "http://github.com/bincyber/pkictl", "keywords": "vault pki kubernetes public key infrastructure security", "license": "MPL", "maintainer": "", "maintainer_email": "", "name": "pkictl", "package_url": "https://pypi.org/project/pkictl/", "platform": "any", "project_url": "https://pypi.org/project/pkictl/", "project_urls": { "Homepage": "http://github.com/bincyber/pkictl" }, "release_url": "https://pypi.org/project/pkictl/0.2.1/", "requires_dist": [ "PyYAML", "requests", "voluptuous" ], "requires_python": ">=3.6", "summary": "A command-line utility for declaratively provisioning PKI in Hashicorp Vault", "version": "0.2.1" }, "last_serial": 4829394, "releases": { "0.1.1": [ { "comment_text": "", "digests": { "md5": "ddface49ad1ea6430e6152de832604c2", "sha256": "39c7903fb7786d7e885df3a5d3608848d03090174aa29f600c65cb7307f12ac9" }, "downloads": -1, "filename": "pkictl-0.1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "ddface49ad1ea6430e6152de832604c2", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 17683, "upload_time": "2018-11-10T22:04:37", "url": "https://files.pythonhosted.org/packages/e7/85/1eddc91aade7a77a6462e953d0bd0ddcd4298ec7c7e08e929d4d9849713c/pkictl-0.1.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9caeef56795de0ff98788a7d4191de15", "sha256": "ac14d15895fb6c58e591c93d9eafeb119136661791788d9886c548181100c54a" }, "downloads": -1, "filename": "pkictl-0.1.1.tar.gz", "has_sig": false, "md5_digest": "9caeef56795de0ff98788a7d4191de15", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 10802, "upload_time": "2018-11-10T22:04:38", "url": "https://files.pythonhosted.org/packages/c4/b5/4fde5e3ba8654fa44a33c1e1726bd244afef9c43738bb5cda878f2adbe27/pkictl-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "4f1ab70fc9cfd49ea202168105fa5842", "sha256": "5a63d8ded4b9d2220dd20c63eec62bc3b0669e6bd6a512bf79c38c7d1eb55cf7" }, "downloads": -1, "filename": "pkictl-0.1.2-py3-none-any.whl", "has_sig": false, "md5_digest": "4f1ab70fc9cfd49ea202168105fa5842", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 17793, "upload_time": "2018-11-13T03:48:08", "url": "https://files.pythonhosted.org/packages/ac/e7/02d6bc45302f2a34991084d82007240b977c501a0ebb072dec1489f5162a/pkictl-0.1.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "99bd42fb43b6ab031e915e83aaa78b06", "sha256": "1c7b5e7c462c159e3ac38f64f41467b283a77d7dc7c01f41d35f1cc6ff02a64f" }, "downloads": -1, "filename": "pkictl-0.1.2.tar.gz", "has_sig": false, "md5_digest": "99bd42fb43b6ab031e915e83aaa78b06", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 10971, "upload_time": "2018-11-13T03:48:10", "url": "https://files.pythonhosted.org/packages/c9/59/296d36449ca32ec6ce6dbea29224b99354e40bd3bd8efa9158adb4e6a027/pkictl-0.1.2.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "5865de754217ec8898614402a64b520b", "sha256": "6f85d29bb7dbda0c3eb5da3c5942d46bba7ecfbd72d6568f8062baafd94e7b7f" }, "downloads": -1, "filename": "pkictl-0.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "5865de754217ec8898614402a64b520b", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 18044, "upload_time": "2018-11-16T14:35:55", "url": "https://files.pythonhosted.org/packages/16/8d/f283bc9d79a2ffd4e4b9ef6c9931dafe6db756705a2a0a70ef3c5ea611b4/pkictl-0.2.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9bd16f1cf9b2f43c0b56173fdcafe471", "sha256": "683fad9a81de318f5695a4fc20db9b7358d2760a8932fafb2705d323790bcb32" }, "downloads": -1, "filename": "pkictl-0.2.0.tar.gz", "has_sig": false, "md5_digest": "9bd16f1cf9b2f43c0b56173fdcafe471", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 11306, "upload_time": "2018-11-16T14:35:56", "url": "https://files.pythonhosted.org/packages/3a/38/eda9999f3292c645ded36ed6070283b3d125f3ccf51b5e6509d3b61c002e/pkictl-0.2.0.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "c6482b966c83222c4bf7a5e115f80045", "sha256": "3936649928c213744d31821a9b78a6702be82f4e1fa4bd5b0d40ebc9f29cbfe8" }, "downloads": -1, "filename": "pkictl-0.2.1-py3-none-any.whl", "has_sig": false, "md5_digest": "c6482b966c83222c4bf7a5e115f80045", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 18083, "upload_time": "2019-02-16T18:19:27", "url": "https://files.pythonhosted.org/packages/90/8c/982fe1c6726e12b62fb2c0b073fd8e99b22865912558a842753f7e4ec71a/pkictl-0.2.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2968f7d7fb0b4c611cffc8fe6643ac44", "sha256": "6c26775de3f47c0535542fcc9850ec50cc459907054a702cd64970b7c1fb585a" }, "downloads": -1, "filename": "pkictl-0.2.1.tar.gz", "has_sig": false, "md5_digest": "2968f7d7fb0b4c611cffc8fe6643ac44", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 11360, "upload_time": "2019-02-16T18:19:28", "url": "https://files.pythonhosted.org/packages/55/57/0513231c0caec20144c9650a0df741d5e4a7b405c8393aff652f88332618/pkictl-0.2.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "c6482b966c83222c4bf7a5e115f80045", "sha256": "3936649928c213744d31821a9b78a6702be82f4e1fa4bd5b0d40ebc9f29cbfe8" }, "downloads": -1, "filename": "pkictl-0.2.1-py3-none-any.whl", "has_sig": false, "md5_digest": "c6482b966c83222c4bf7a5e115f80045", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 18083, "upload_time": "2019-02-16T18:19:27", "url": "https://files.pythonhosted.org/packages/90/8c/982fe1c6726e12b62fb2c0b073fd8e99b22865912558a842753f7e4ec71a/pkictl-0.2.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2968f7d7fb0b4c611cffc8fe6643ac44", "sha256": "6c26775de3f47c0535542fcc9850ec50cc459907054a702cd64970b7c1fb585a" }, "downloads": -1, "filename": "pkictl-0.2.1.tar.gz", "has_sig": false, "md5_digest": "2968f7d7fb0b4c611cffc8fe6643ac44", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 11360, "upload_time": "2019-02-16T18:19:28", "url": "https://files.pythonhosted.org/packages/55/57/0513231c0caec20144c9650a0df741d5e4a7b405c8393aff652f88332618/pkictl-0.2.1.tar.gz" } ] }