{"id":37679746,"url":"https://github.com/akimrx/python-yc-lockbox","last_synced_at":"2026-01-16T12:22:45.007Z","repository":{"id":229138306,"uuid":"775342166","full_name":"akimrx/python-yc-lockbox","owner":"akimrx","description":"Python Yandex Lockbox client (secrets vault).","archived":false,"fork":false,"pushed_at":"2024-04-02T08:10:03.000Z","size":310,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-11-29T02:51:53.470Z","etag":null,"topics":["cloud","lockbox","python-lockbox-client","python3","secrets","security","vault","yandex","yandex-cloud","yandex-lockbox","yandex-lockbox-client","yandexcloud","yc-lockbox","yc-secrets"],"latest_commit_sha":null,"homepage":"https://akimrx.github.io/python-yc-lockbox/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/akimrx.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"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}},"created_at":"2024-03-21T07:59:09.000Z","updated_at":"2024-04-13T19:38:52.000Z","dependencies_parsed_at":"2024-03-22T08:59:37.710Z","dependency_job_id":null,"html_url":"https://github.com/akimrx/python-yc-lockbox","commit_stats":null,"previous_names":["akimrx/python-yc-lockbox"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/akimrx/python-yc-lockbox","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akimrx%2Fpython-yc-lockbox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akimrx%2Fpython-yc-lockbox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akimrx%2Fpython-yc-lockbox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akimrx%2Fpython-yc-lockbox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/akimrx","download_url":"https://codeload.github.com/akimrx/python-yc-lockbox/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akimrx%2Fpython-yc-lockbox/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28478582,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T11:59:17.896Z","status":"ssl_error","status_checked_at":"2026-01-16T11:55:55.838Z","response_time":107,"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":["cloud","lockbox","python-lockbox-client","python3","secrets","security","vault","yandex","yandex-cloud","yandex-lockbox","yandex-lockbox-client","yandexcloud","yc-lockbox","yc-secrets"],"created_at":"2026-01-16T12:22:44.325Z","updated_at":"2026-01-16T12:22:44.978Z","avatar_url":"https://github.com/akimrx.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Yandex Lockbox Client\n\n[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/yc-lockbox.svg)](https://pypi.org/project/yc-lockbox/)\n[![PyPi Package](https://img.shields.io/pypi/v/yc-lockbox.svg)](https://pypi.org/project/yc-lockbox/)\n[![Codecov](https://codecov.io/gh/akimrx/python-yc-lockbox/branch/master/graph/badge.svg)](https://app.codecov.io/gh/akimrx/python-yc-lockbox)\n[![Tests](https://github.com/akimrx/python-yc-lockbox/workflows/Tests/badge.svg)](https://github.com/akimrx/python-yc-lockbox)\n\nThis library is a simple client for working with **[Yandex Lockbox](https://cloud.yandex.ru/en/docs/lockbox/)** over [REST API](https://cloud.yandex.ru/en/docs/lockbox/api-ref/), simplifying work with secrets and allowing you to work with them in the OOP paradigm.\n\nSupports two modes: synchronous and asynchronous.\n\n**[Full library documentation link](https://akimrx.github.io/python-yc-lockbox/)**\n\n**Supported Python versions**:\n\n* 3.10\n* 3.11\n* 3.12\n\n**Dependencies:**\n\n* [Pydantic V2](https://github.com/pydantic/pydantic)\n* [Crypthography](https://github.com/pyca/cryptography)\n* [PyJWT](https://github.com/jpadilla/pyjwt)\n* [Requests](https://github.com/psf/requests)\n\n\n**Extra dependencies:**\n\n* [aiohttp](https://github.com/aio-libs/aiohttp)\n\n\n**Currently, the following operations are not supported by the library:**\n\n* List secret access bindings\n* Set secret access bindings\n* Update secret access bindings\n* List secret operations\n\n\n**In the near future release:**\n\n- [x] Tests\n- [x] Async client implementation\n- [ ] Implement access bindings methods and view operations\n- [ ] Ansible action and lookup plugins\n\n\n## Install\n\nInstalling via [pip](https://pypi.org/project/yc-lockbox/):\n\n```\npip install yc-lockbox\n```\n\nAlso, you can install from source with:\n\n```\ngit clone https://github.com/akimrx/python-yc-lockbox\ncd python-yc-lockbox \nmake install\n```\n\nFor async mode support use\n\n```\npip install yc-lockbox[aio]\n```\n\n\n## Usage\n\n\n* **Authenticate via your [OAuth token](https://oauth.yandex.com/authorize?response_type=token\u0026client_id=1a6990aa636648e9b2ef855fa7bec2fb)**\n\n```python\nfrom yc_lockbox import YandexLockboxClient\n\nlockbox = YandexLockboxClient(\"y0_xxxxxxxxxxxx\")\n```\n\n* **Authenticate via [IAM token](https://cloud.yandex.com/en/docs/iam/operations/iam-token/create)**\n\n\u003e If you pass a IAM token as credentials, you need to take care of the freshness of the token yourself.\n\n```python\nfrom yc_lockbox import YandexLockboxClient\n\nlockbox = YandexLockboxClient(\"t1.xxxxxx.xxxxxxx\")\n```\n\n\n\n* **Authenticate using [service account key](https://cloud.yandex.com/en/docs/iam/operations/authorized-key/create#cli_1)**\n\n```python\nimport json\nfrom yc_lockbox import YandexLockboxClient\n\nwith open(\"/path/to/key.json\", \"r\") as keyfile:\n    credentials = keyfile.read()\n\nlockbox = YandexLockboxClient(credentials)\n```\n\n### Create a new secret\n\n```python\nfrom yc_lockbox import YandexLockboxClient, INewSecret, INewSecretPayloadEntry\n\nlockbox = YandexLockboxClient(\"oauth_or_iam_token\")\n\ncreate_secret_operation = lockbox.create_secret(\n    INewSecret(\n    folder_id=\"b1xxxxxxxxxxxxxx\",\n    name=\"my-secret\",\n    version_payload_entries=[\n        INewSecretPayloadEntry(key=\"secret_entry_1\", text_value=\"secret_entry_text_value\"),\n        INewSecretPayloadEntry(key=\"secret_entry_2\", binary_value=\"secret_entry_binary_value\".encode()),\n    ],\n    )\n)\n\nif create_secret_operation.done:\n    new_secret = create_secret_operation.resource\n    print(new_secret.id)\n    new_secret.deactivate()\n```\n\n\n### Get secret from Lockbox\n\n```python\nfrom yc_lockbox import YandexLockboxClient, Secret\n\nlockbox = YandexLockboxClient(\"oauth_or_iam_token\")\n\nsecret: Secret = lockbox.get_secret(\"e6qxxxxxxxxxx\")\nprint(secret.status, secret.name)\n\npayload = secret.payload(version_id=secret.current_version.id)  # id is optional, by default using current version\nprint(payload.entries)  # list of SecretPayloadEntry objects\n\n# Direct access\n\nentry = payload[\"secret_entry_1\"]  # or payload.get(\"secret_entry_1\")\n\nprint(entry.text_value)  # return MASKED value like ***********\nprint(entry.reveal_text_value())  # similar to entry.text_value.get_secret_value()\n```\n\n\n### Add new version of secret\n\n```python\nfrom yc_lockbox import YandexLockboxClient, Secret, INewSecretVersion, INewSecretPayloadEntry\n\nlockbox = YandexLockboxClient(\"oauth_or_iam_token\")\n\nsecret: Secret = lockbox.get_secret(\"e6qxxxxxxxxxxxx\")\n\nsecret.add_version(\n    INewSecretVersion(\n        description=\"a new version\",\n        base_version_id=secret.current_version.id,\n        payload_entries= [\n            INewSecretPayloadEntry(key=\"secret_entry_1\", text_value=\"secret_entry_text_value\"),\n            INewSecretPayloadEntry(key=\"secret_entry_2\", binary_value=\"secret_entry_binary_value\"),\n        ]\n    )\n)\n\n# alternative\nlockbox.add_secret_version(\n    \"secret_id\",\n    version=INewSecretVersion(\n        description=\"a new version\",\n        base_version_id=secret.current_version.id,\n        payload_entries=[INewSecretPayloadEntry(...), INewSecretPayloadEntry(...)]\n    )\n)\n```\n\n\n### Other operations with secret\n\n```python\nfrom yc_lockbox import YandexLockboxClient\n\nlockbox = YandexLockboxClient(\"oauth_or_iam_token\")\n\n\nfor secret in lockbox.list_secrets(folder_id=\"b1xxxxxxxxxx\", iterator=True):\n    print(secret.name, secret.status)\n\n    secret.deactivate()\n    secret.activate()\n\n    for version in secret.list_versions(iterator=True):  # if iterator=False returns paginated list with ``next_page_token``\n        if version.id != secret.current_version.id:\n            version.schedule_version_destruction()\n            version.cancel_version_destruction()\n\n```\n\n## Async mode\n\nThe client supports asynchronous mode using the aiohttp library. The signature of the methods does not differ from the synchronous implementation.\n\n\nJust import async client:\n\n```python\n\nfrom yc_lockbox import AsyncYandexLockboxClient\n\nlockbox = AsyncYandexLockboxClient(\"oauth_or_iam_token\")\n```\n\nAlternative:\n\n```python\n\nfrom yc_lockbox import YandexLockboxFacade\n\nlockbox = YandexLockboxFacade(\"oauth_or_iam_token\", enable_async=True).client\n```\n\nExample usage:\n\n```python\nsecret: Secret = await lockbox.get_secret(\"e6qxxxxxxxxxx\")\npayload = await secret.payload()\nprint(payload.entries)  # list of SecretPayloadEntry objects\n\n# Direct access\n\nentry = payload[\"secret_entry_1\"]  # or payload.get(\"secret_entry_1\")\n\nprint(entry.text_value)  # return MASKED value like ***********\nprint(entry.reveal_text_value())  # similar to entry.text_value.get_secret_value()\n\n# Async iterators\n\nsecret_versions = await secret.list_versions(iterator=True)\n\nasync for version in secret_versions:\n    if version.id != secret.current_version.id:\n        await version.schedule_version_destruction()\n        await version.cancel_version_destruction()\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakimrx%2Fpython-yc-lockbox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fakimrx%2Fpython-yc-lockbox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakimrx%2Fpython-yc-lockbox/lists"}