atsh
Python SDK for the developer tools at atsh.in.
pip install atsh
Requires Python 3.9+.
What's in this package
atsh is the Python home for atsh.in's developer tools. Each tool
lives in its own subpackage and imports independently:
from atsh.env import Env
More subpackages are added as the tools they wrap are released. The list below reflects what is actually shipped in this version.
| Subpackage | What it does |
|---|---|
atsh.env |
SDK for the zero-knowledge secret manager at env.atsh.in |
atsh.env
Zero-knowledge secret manager SDK. Every project has its own master pass; the server stores only ciphertext it cannot read.
Source: github.com/atsh-here/atsh-env-py
Quick start
import os
from atsh.env import Env
with Env.connect(
base_url="https://env.atsh.in/api/v1",
project="acme",
environment="dev",
token=os.environ["ATSH_ENV_TOKEN"],
master_pass=os.environ["ATSH_ENV_MASTER_PASS"],
) as env:
print(env.get("DATABASE_URL"))
print(env.get("Configs/APP_CONFIG"))
print(env.get("Configs/stripe/SECRET_KEY"))
How it works
Every project has a master pass chosen at init. It never leaves the client. Argon2id(master_pass, kekSalt) derives a KEK, which unwraps a per-project DEK. Every secret, file, store entry, and certificate blob is encrypted with AES-256-GCM under that DEK before it reaches the server.
The envelope is byte-compatible with the browser, the CLI, and the
TypeScript SDK (@atsh/env).
Path addressing
| Path | What it addresses |
|---|---|
DATABASE_URL |
Environment-root secret |
Configs/APP_CONFIG |
Secret in folder Configs |
Configs/stripe/SECRET_KEY |
Entry in store stripe (folder Configs) |
Env
Connect:
env = Env.connect(
base_url="https://env.atsh.in/api/v1",
project="acme",
environment="dev",
token="atsh_env_...",
master_pass="...",
)
Also accepts dek_override=b"..." to skip the crypto when you already
have the DEK (vault-cache path). Mutually exclusive with master_pass.
Secrets:
env.get("KEY")
env.set("KEY", "value")
env.set("KEY", "value", comment="rotated")
env.delete("KEY")
env.pull(scope="all")
env.pull(scope="global")
Files:
env.upload_file("app.json", json_bytes, folder_id=None)
env.file("Configs/app.json").bytes()
env.file("Configs/app.json").text()
env.file("Configs/app.json").json()
env.file("app.json").replace(new_bytes)
Stores:
store = env.store("Configs/stripe")
store.entries()
store.set("KEY", "value")
store.delete("KEY")
store.versions("KEY")
store.revert("KEY", to=3)
Certificates:
cert = env.certificate("wildcard-acme")
cert.cert(); cert.key(); cert.chain()
cert.upload_cert(pem_bytes)
cert.upload_key(key_bytes)
cert.upload_chain(chain_bytes)
cert.versions()
cert.revert(to=3)
Universal secrets (account-scoped, server-readable):
u = env.universal()
u.list()
u.get("SHARED_TOKEN")
u.set("SHARED_TOKEN", "value")
u.delete("SHARED_TOKEN")
Folders:
env.list_folders()
env.create_folder("Configs")
env.create_folder("Sub", parent_id=folder_id)
env.delete_folder("Configs")
Utilities:
env.manifest_tree()
env.refresh_manifest()
env.snapshot()
env.close()
AtshEnvClient
Low-level REST client. No crypto, no state.
from atsh.env import AtshEnvClient
with AtshEnvClient("https://env.atsh.in/api/v1", "atsh_env_...") as c:
projects = c.projects.list()
manifest = c.projects.manifest("acme", environment="dev")
secrets = c.secrets.list(project_id, env="env_...")
Workflows
from atsh.env import (
AtshEnvClient,
create_and_initialize_project,
initialize_project,
)
client = AtshEnvClient(base_url, account_token)
result = create_and_initialize_project(
client=client,
name="acme",
master_pass="...",
)
print(result.project["slug"], result.project_token)
initialize_project(
client=client,
project_id="p_...",
init_token="atsh_init_...",
master_pass="...",
mint={"name": "cli"},
)
Errors
from atsh.env import (
AtshEnvError,
VaultLockedError,
ApprovalRequiredError,
NotFoundError,
ConflictError,
ProtectedEnvironmentError,
)
Protected environments
If the environment has protected: true on the server, every write
raises ProtectedEnvironmentError unless you pass
allow_protected=True:
env.set("KEY", "value", allow_protected=True)
License
MIT — see LICENSE.
Metadata
Release files for atsh 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| atsh-0.1.1.tar.gz | 21.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| atsh-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 44.4 kB
Release files / atsh-0.1.1.tar.gz
| Download URL | atsh-0.1.1.tar.gz |
|---|---|
| Size | 21.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
57a0f406632ff4a7c93fafc433519a3437f1e8e829e28df6b509dff0c2d32d8e
|
|
BLAKE2b-256 checksum How to use checksums |
0a524e85eaae9a2abf04d198da9dc82d6fbacebd4147ddc14f88accf80bf6b0b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|
Release files / atsh-0.1.1-py3-none-any.whl
| Download URL | atsh-0.1.1-py3-none-any.whl |
|---|---|
| Size | 23.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c3be3ffcd41e86815e990ea1669e779f0f7c45160b009991649e486acd7000ce
|
|
BLAKE2b-256 checksum How to use checksums |
ebc1abb92974f2538593bce1fa8b9896c8c663576ebc23de5019c8f5efabe450
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|