{"id":40224656,"url":"https://github.com/lewoudar/certipie","last_synced_at":"2026-01-19T22:30:52.727Z","repository":{"id":42533184,"uuid":"458358966","full_name":"lewoudar/certipie","owner":"lewoudar","description":"A helper to generate certificate signing request and self-signed certificates","archived":false,"fork":false,"pushed_at":"2024-01-13T18:40:48.000Z","size":229,"stargazers_count":5,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-04T22:22:18.507Z","etag":null,"topics":["certificate","cryptography","csr","fastapi"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lewoudar.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-02-11T22:31:21.000Z","updated_at":"2024-01-16T17:34:46.000Z","dependencies_parsed_at":"2023-11-27T08:28:02.846Z","dependency_job_id":"3842967c-aab6-437d-aa15-814755a6042b","html_url":"https://github.com/lewoudar/certipie","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/lewoudar/certipie","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lewoudar%2Fcertipie","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lewoudar%2Fcertipie/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lewoudar%2Fcertipie/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lewoudar%2Fcertipie/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lewoudar","download_url":"https://codeload.github.com/lewoudar/certipie/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lewoudar%2Fcertipie/sbom","scorecard":{"id":586474,"data":{"date":"2025-08-11","repo":{"name":"github.com/lewoudar/certipie","commit":"972524cc9af8c8245cc48807b47cdf7adb4eb100"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.5,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":0,"reason":"Found 0/27 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/ci.yml:1","Warn: no topLevel permission defined: .github/workflows/publish.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/lewoudar/certipie/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/lewoudar/certipie/ci.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yml:40: update your workflow using https://app.stepsecurity.io/secureworkflow/lewoudar/certipie/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/lewoudar/certipie/publish.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/publish.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/lewoudar/certipie/publish.yml/main?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/ci.yml:29","Warn: pipCommand not pinned by hash: .github/workflows/publish.yml:21","Info:   0 out of   4 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned","Info:   0 out of   2 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 5 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"20 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: PYSEC-2024-230 / GHSA-248v-346w-9cwc","Warn: Project is vulnerable to: GHSA-3ww4-gg4f-jr7f","Warn: Project is vulnerable to: PYSEC-2024-225 / GHSA-6vqw-3v5j-54x4","Warn: Project is vulnerable to: GHSA-9v9h-cgj8-h64p","Warn: Project is vulnerable to: GHSA-h4gh-qq45-vh27","Warn: Project is vulnerable to: PYSEC-2023-254 / GHSA-jfhm-5ghh-2f97","Warn: Project is vulnerable to: PYSEC-2024-38 / GHSA-2jv5-9r88-3w3p","Warn: Project is vulnerable to: GHSA-vqfr-h8mv-ghfj","Warn: Project is vulnerable to: PYSEC-2023-242 / GHSA-8r96-8889-qg2x","Warn: Project is vulnerable to: PYSEC-2024-60 / GHSA-jjg7-2v4v-x38h","Warn: Project is vulnerable to: GHSA-59g5-xgcq-4qw3","Warn: Project is vulnerable to: GHSA-9hjg-9r4m-mvj7","Warn: Project is vulnerable to: GHSA-9wx4-h78v-vm56","Warn: Project is vulnerable to: PYSEC-2025-49 / GHSA-5rjg-fvgr-3xxf","Warn: Project is vulnerable to: GHSA-cx63-2mw6-8hw5","Warn: Project is vulnerable to: GHSA-2c2j-9gv5-cj73","Warn: Project is vulnerable to: GHSA-f96h-pmfr-66vw","Warn: Project is vulnerable to: GHSA-34jh-p97f-mpxf","Warn: Project is vulnerable to: GHSA-pq67-6m6q-mj2v","Warn: Project is vulnerable to: PYSEC-2024-187 / GHSA-rqc4-2hc7-8c8v"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-20T20:38:41.979Z","repository_id":42533184,"created_at":"2025-08-20T20:38:41.979Z","updated_at":"2025-08-20T20:38:41.979Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28587238,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-19T20:45:59.482Z","status":"ssl_error","status_checked_at":"2026-01-19T20:45:41.500Z","response_time":67,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["certificate","cryptography","csr","fastapi"],"created_at":"2026-01-19T22:30:48.336Z","updated_at":"2026-01-19T22:30:52.714Z","avatar_url":"https://github.com/lewoudar.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# certipie\n\n[![Pypi version](https://img.shields.io/pypi/v/certipie.svg)](https://pypi.org/project/certipie/)\n[![](https://github.com/lewoudar/certipie/workflows/CI/badge.svg)](https://github.com/lewoudar/certipie/actions/)\n[![Coverage Status](https://codecov.io/gh/lewoudar/certipie/branch/main/graphs/badge.svg?branch=main)](https://codecov.io/gh/lewoudar/certipie)\n[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/lewoudar/certipie)\n[![License Apache 2](https://img.shields.io/hexpm/l/plug.svg)](http://www.apache.org/licenses/LICENSE-2.0)\n[![Poetry](https://img.shields.io/endpoint?url=https://python-poetry.org/badge/v0.json)](https://github.com/lewoudar/certipie)\n\nA utility library to create certificate signing request and self-signed certificates.\n\n## Why?\n\nThere are three main reasons why I decide to do this:\n\n- I am a *nerd* who loves to code. Yeah, I need to be honest here, it was an opportunity for me to play with the\n  excellent [cryptography](https://cryptography.io/en/latest/) library.\n- I currently work in a company where we deal a lot with certificates, and I know it can be handy to have a simple tool\n  to generate certificate signing request, so I decide to create one.\n- When creating or working with network servers, we often need to test certificate handling, so it is convenient to have\n  a tool to quickly generate a self-signed certificate.\n\nNotes:\n\n- If you want a tool to handle a whole certificate life cycle for your project, consider using a library like\n  [certbot](https://eff-certbot.readthedocs.io/en/stable/).\n- If you just want a tool to create certificates on the fly during unit tests, consider using\n  [trustme](https://trustme.readthedocs.io/en/latest/).\n\n## Installation\n\nThe minimal python version supported is **3.9**. You can install the library using **pip** with the following command:\n\n```shell\n$ pip install certipie\n```\n\nYou can also use an alternative package manager like [poetry](https://python-poetry.org/docs/):\n\n```shell\n$ poetry add certipie\n```\n\n## Usage\n\nThere are three ways to use certipie.\n\n### The command line interface\n\nThis is probably the main way to use it. The project includes a convenient `cert` command line interface.\n\n```shell\n$ cert\nUsage: cert [OPTIONS] COMMAND [ARGS]...\n\n  A cli to generate certificate signing request and self-signed certificate\n  that can be used for testing purpose.\n\nOptions:\n  --version   Show the version and exit.\n  -h, --help  Show this message and exit.\n\nCommands:\n  auto-cert           Creates a self-signed certificate useful for tests.\n  csr                 Creates a certificate signing request file given...\n  install-completion  Install completion script for bash, zsh and fish...\n  rsa                 Creates a pair of private/public keys using the RSA...\n  server              Serves a swagger UI where you can perform the same...\n```\n\n#### install-completion\n\nThe first command you will want to use is `install-completion` like the name said will allow options and commands\ncompletion. The shells currently supported are **bash**, **fish** and **zsh**.\n\n```shell\n$ cert install-completion\n```\n\n#### rsa\n\nTo create a certificate signing request or a self-signed certificate, you need a private key. The `cert` command allows\nyou to create an **RSA** private key which is one of the most common (if not the most common) private keys used for this\ntype of operation.\n\n```shell\n$ cert rsa\nEnter the passphrase [passphrase]:\nRepeat for confirmation:\nThe pair of keys was successfully in ...\n```\n\nNote: On all commands, you can use `-h` option to get their usage documentation.\n\n#### csr\n\nThis commands helps you create a certificate signing request.\n\n```shell\n$ cert csr -f csr.pem\nOrganization: orga\nState: Ile-de-France\nCountry: FR\nCity: Paris\nName: site.com\nThe certificate signing request has been successfully created in /home/kevin/...\n```\n\nNotes:\n\n- In the previous example since no private key was passed as input, the `csr` command creates an **RSA** one with no\n  password in the same directory where the certificate signing request is created. If you want to provide one, use the\n  `-k` option and gives the path to the private key, e.g: `cert csr -k /path/to/private/key`. It is not mandatory that\n  the private key is of type RSA. In fact other algorithms are supported like DSA or elliptic curve. For a full list of\n  supported algorithms, look `PrivateKey` type in module `certipie.types`.\n- If you pass a key file, you will be prompted to give the password. If you don't provide a password to your private\n  key, just type `Enter` to continue.\n- The `--country` option must be a two-letters value. To know the two-letters code of a country, you can check this\n  [website](https://www.iban.com/country-codes).\n- The `--name` option value is used as the domain name to submit for the certificate signing request. In the previous\n  example, it will be `site.com`. Wildcards like `*.site.com` are supported.\n- If you want to include many domain names in the certificate signing request, not only the `--name` value, you can use\n  the `--alt-names` option like the following: `cert csr --alt-names=site.com,foo.site.com`. The values **must**\n  be separated by commas.\n\n#### auto-cert\n\nThis command helps you create a self-signed certificate useful when you want to test a network server like an HTTP\nserver.\n\n```shell\n$ cert auto-cert -f cert.pem --validity=360\nOrganization: orga\nState: Ile-de-France\nCountry: FR\nCity: Paris\nThe self-signed certificate has been successfully created in /home/kevin/...\n```\n\nNotes:\n\n- The notes from the `csr` command also applies here.\n- Since we often work on our own computer in this case, `localhost` is the default `--name` option.\n- `--alt-names` also accepts ip adresses and networks. You can have a value like the following:\n  `cert auto-cert --alt-names=localhost,192.168.1.0/24`.\n- `--validity` option represents the number of days the certificate will be valid. If not provided, it is **365**.\n\n#### server\n\nThis commands runs a server which serves a Swagger UI where you can perform the previous commands explained above. This\nis handy if you want non-technical staff to be able to use the command line features.\n\n```shell\n$ cert server\n```\n\nIf you open a browser on http://localhost:8000 you will see the swagger documentation.\n![](images/cert_api.png)\n\nUnder the hood the server used is [hypercorn](https://pgjones.gitlab.io/hypercorn). You can configure it passing a\n*toml* configuration file. To know all the settings available, refer to the\n[official documentation](https://pgjones.gitlab.io/hypercorn/how_to_guides/configuring.html).\n\n```shell\n$ cert server -c /path/to/toml/file\n```\n\n### The REST API\n\nFollowing the previous section about serving a swagger UI, if you think that it does not well suits your organization,\nyou can adjust it. The api is created using the [FastAPI](https://fastapi.tiangolo.com/) web framework. For example if\nyou want to integrate it in your own fastapi application, you can use the router provided by certipie.\n\nThis way you can adjust the url used for the certificate routes, for example `/certificate` instead of `/certs`, change\ndocumentation url, add some authentication to routes, etc...\nThe [router](https://fastapi.tiangolo.com/tutorial/bigger-applications/) concept is a powerful feature from FastAPI.\n\n```python\nfrom fastapi import FastAPI\nfrom certipie import router\n\napp = FastAPI(\n    title='certificate api',\n    description='Your description',\n    redoc_url=None,\n    docs_url='/documentation'\n)\napp.include_router(router, prefix='/certificate', tags=['certificate'])\n```\n\nTransform the api to suit your needs :)\n\n### The certipie API\n\nThe last way to leverage certipie is to interact programmatically with its api. The following functions are exposed:\n\n- `create_private_key`: Creates an RSA private key.\n- `get_public_key_from_private_key`: Extracts a public key from a private key.\n- `create_csr`: Creates a certificate signing request.\n- `create_auto_cert`: Creates a self-signed certificate.\n\nNormally the api usage should be straightforward. The behaviour is the same as the command line. You can also look at\ntests if you are blocked.\n\nHere is a snippet on how to create a certificate signing request using `create_csr`:\n\n```python\nfrom certipie import create_csr\n\ncreate_csr(\n    'csr.pem',\n    'FR',\n    'Ile-de-France',\n    'Paris',\n    'organization',\n    'site.com',\n    alternative_names=['site.com', 'foo.site.com'],\n    private_key='key.pem',\n    passphrase='passphrase'\n)\n```\n\nThere are two others objets exported:\n\n- `app`: The fastapi application used when running `cert server` command. It is exposed so that you can\n  [mount](https://fastapi.tiangolo.com/advanced/sub-applications/) it in another application if you want.\n- `PrivateKey`: The type annotation for all the private keys supported by the `cryptography` library.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flewoudar%2Fcertipie","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flewoudar%2Fcertipie","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flewoudar%2Fcertipie/lists"}