lambdavault 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,41 @@
1
+ Metadata-Version: 2.4
2
+ Name: lambdavault
3
+ Version: 0.1.0
4
+ Summary: HashiCorp Vault on AWS Lambda + S3 + KMS, ≈ $0 when idle. The vault CLI, hvac and the Terraform vault provider talk to it unchanged; this package is the helper: status, output.
5
+ Author: Frank Zhang
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/cloudformer/lambdavault
8
+ Project-URL: Repository, https://github.com/cloudformer/lambdavault
9
+ Project-URL: Deploy, https://github.com/cloudformer/lambdavault#quick-start
10
+ Project-URL: Compatibility, https://github.com/cloudformer/lambdavault/blob/main/tests/compat/REPORT.md
11
+ Project-URL: Changelog, https://github.com/cloudformer/lambdavault/blob/main/CHANGELOG.md
12
+ Project-URL: Issues, https://github.com/cloudformer/lambdavault/issues
13
+ Keywords: serverless,aws,lambda,vault,hashicorp-vault,secrets,kms
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Topic :: Security
19
+ Requires-Python: >=3.9
20
+ Description-Content-Type: text/markdown
21
+
22
+ # lambdavault
23
+
24
+ **HashiCorp Vault, truly serverless: the official Vault binary on AWS Lambda, data in S3, auto-unseal by KMS,
25
+ ≈ $1 a month when idle.** Part of [Redefine AWS Serverless](https://github.com/topics/redefine-aws-serverless).
26
+
27
+ ![lambdavault architecture](https://raw.githubusercontent.com/cloudformer/lambdavault/main/docs/architecture.svg)
28
+
29
+ The vault CLI, hvac and the Terraform vault provider are the clients — unchanged, only `VAULT_ADDR` points at
30
+ the Lambda. This package is the helper around a deployment:
31
+
32
+ ```bash
33
+ pip install lambdavault
34
+ lambdavault status # initialized / sealed / version / latency (address from terraform output)
35
+ eval "$(lambdavault output)" # export VAULT_ADDR for the vault CLI
36
+ vault operator init -recovery-shares=1 -recovery-threshold=1 # once
37
+ vault kv get kvv2/app
38
+ ```
39
+
40
+ Deploy the server from the [main repository](https://github.com/cloudformer/lambdavault) with Terraform.
41
+ Compatibility with a normal Vault: [REPORT.md](https://github.com/cloudformer/lambdavault/blob/main/tests/compat/REPORT.md).
@@ -0,0 +1,20 @@
1
+ # lambdavault
2
+
3
+ **HashiCorp Vault, truly serverless: the official Vault binary on AWS Lambda, data in S3, auto-unseal by KMS,
4
+ ≈ $1 a month when idle.** Part of [Redefine AWS Serverless](https://github.com/topics/redefine-aws-serverless).
5
+
6
+ ![lambdavault architecture](https://raw.githubusercontent.com/cloudformer/lambdavault/main/docs/architecture.svg)
7
+
8
+ The vault CLI, hvac and the Terraform vault provider are the clients — unchanged, only `VAULT_ADDR` points at
9
+ the Lambda. This package is the helper around a deployment:
10
+
11
+ ```bash
12
+ pip install lambdavault
13
+ lambdavault status # initialized / sealed / version / latency (address from terraform output)
14
+ eval "$(lambdavault output)" # export VAULT_ADDR for the vault CLI
15
+ vault operator init -recovery-shares=1 -recovery-threshold=1 # once
16
+ vault kv get kvv2/app
17
+ ```
18
+
19
+ Deploy the server from the [main repository](https://github.com/cloudformer/lambdavault) with Terraform.
20
+ Compatibility with a normal Vault: [REPORT.md](https://github.com/cloudformer/lambdavault/blob/main/tests/compat/REPORT.md).
@@ -0,0 +1,4 @@
1
+ """lambdavault: HashiCorp Vault on AWS Lambda + S3 + KMS. The vault CLI, hvac and the Terraform vault provider
2
+ are the clients; this package is the helper around a deployment (`lambdavault status | output`)."""
3
+
4
+ __version__ = "0.1.0"
@@ -0,0 +1,3 @@
1
+ from .cli import main
2
+
3
+ main()
@@ -0,0 +1,87 @@
1
+ """lambdavault: the helper around a deployment. Day-to-day work (and `vault operator init`) is the vault CLI.
2
+
3
+ lambdavault output export VAULT_ADDR=...: eval "$(lambdavault output)"
4
+ lambdavault status is it up: initialized / sealed / version, and how long one call took
5
+
6
+ The address comes from the deployment's local Terraform state (`terraform -chdir=terraform output -json`, run
7
+ from the repo root), or from --addr / $VAULT_ADDR. Nothing is stored anywhere else.
8
+ """
9
+ import argparse
10
+ import json
11
+ import os
12
+ import subprocess
13
+ import sys
14
+ import time
15
+ import urllib.error
16
+ import urllib.request
17
+
18
+ from . import __version__
19
+
20
+
21
+ def address(args):
22
+ if args.addr:
23
+ return args.addr.rstrip("/")
24
+ try:
25
+ r = subprocess.run(["terraform", f"-chdir={args.dir}", "output", "-json"], capture_output=True, text=True)
26
+ except FileNotFoundError:
27
+ r = None
28
+ if r is None or r.returncode:
29
+ sys.exit(f"no address: run from the repo root after terraform apply, or give --addr / VAULT_ADDR "
30
+ f"({(r.stderr.strip()[:200] if r else 'terraform not found')})")
31
+ out = json.loads(r.stdout or "{}")
32
+ if "vault_addr" not in out:
33
+ sys.exit(f"terraform output in {args.dir} has no vault_addr: deploy first (terraform -chdir={args.dir} apply)")
34
+ return out["vault_addr"]["value"]
35
+
36
+
37
+ def call(addr, path, tries=5):
38
+ """GET one Vault API path. A cold start can take seconds and a busy function answers 429: wait and retry."""
39
+ for attempt in range(tries):
40
+ try:
41
+ with urllib.request.urlopen(addr + path, timeout=60) as r:
42
+ return r.status, json.loads(r.read() or b"{}")
43
+ except urllib.error.HTTPError as e:
44
+ if e.code in (429, 502, 503) and attempt < tries - 1:
45
+ time.sleep(1 + attempt)
46
+ continue
47
+ raw = e.read()
48
+ try:
49
+ return e.code, json.loads(raw)
50
+ except ValueError:
51
+ return e.code, {"errors": [raw.decode(errors="replace")[:200]]}
52
+ raise AssertionError("unreachable")
53
+
54
+
55
+ def cmd_status(args):
56
+ addr = address(args)
57
+ t0 = time.time()
58
+ status, health = call(addr, "/v1/sys/health?uninitcode=200&sealedcode=200")
59
+ ms = (time.time() - t0) * 1000
60
+ if status != 200:
61
+ sys.exit(f"{addr} answered {status}: {health}")
62
+ print(f"{addr}\n"
63
+ f" initialized {health.get('initialized')} · sealed {health.get('sealed')} · Vault {health.get('version')}\n"
64
+ f" one call: {ms:.0f} ms (seconds after idle = a cold start) · UI: {addr}/ui/")
65
+ if not health.get("initialized"):
66
+ print(f"next: VAULT_ADDR={addr} vault operator init -recovery-shares=1 -recovery-threshold=1")
67
+
68
+
69
+ def cmd_output(args):
70
+ print(f"export VAULT_ADDR={address(args)}")
71
+
72
+
73
+ def main(argv=None):
74
+ p = argparse.ArgumentParser(prog="lambdavault", description=__doc__.split("\n\n")[0])
75
+ p.add_argument("--version", action="version", version=f"lambdavault {__version__}")
76
+ common = argparse.ArgumentParser(add_help=False)
77
+ common.add_argument("--dir", default="terraform", help="the Terraform directory (default terraform, from the repo root)")
78
+ common.add_argument("--addr", default=os.environ.get("VAULT_ADDR"), help="the Vault address instead of terraform output")
79
+ sub = p.add_subparsers(dest="command", required=True)
80
+ sub.add_parser("output", parents=[common], help="print export VAULT_ADDR=... (eval it)").set_defaults(func=cmd_output)
81
+ sub.add_parser("status", parents=[common], help="initialized / sealed / version / latency").set_defaults(func=cmd_status)
82
+ args = p.parse_args(argv)
83
+ args.func(args)
84
+
85
+
86
+ if __name__ == "__main__":
87
+ main()
@@ -0,0 +1,41 @@
1
+ Metadata-Version: 2.4
2
+ Name: lambdavault
3
+ Version: 0.1.0
4
+ Summary: HashiCorp Vault on AWS Lambda + S3 + KMS, ≈ $0 when idle. The vault CLI, hvac and the Terraform vault provider talk to it unchanged; this package is the helper: status, output.
5
+ Author: Frank Zhang
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/cloudformer/lambdavault
8
+ Project-URL: Repository, https://github.com/cloudformer/lambdavault
9
+ Project-URL: Deploy, https://github.com/cloudformer/lambdavault#quick-start
10
+ Project-URL: Compatibility, https://github.com/cloudformer/lambdavault/blob/main/tests/compat/REPORT.md
11
+ Project-URL: Changelog, https://github.com/cloudformer/lambdavault/blob/main/CHANGELOG.md
12
+ Project-URL: Issues, https://github.com/cloudformer/lambdavault/issues
13
+ Keywords: serverless,aws,lambda,vault,hashicorp-vault,secrets,kms
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Topic :: Security
19
+ Requires-Python: >=3.9
20
+ Description-Content-Type: text/markdown
21
+
22
+ # lambdavault
23
+
24
+ **HashiCorp Vault, truly serverless: the official Vault binary on AWS Lambda, data in S3, auto-unseal by KMS,
25
+ ≈ $1 a month when idle.** Part of [Redefine AWS Serverless](https://github.com/topics/redefine-aws-serverless).
26
+
27
+ ![lambdavault architecture](https://raw.githubusercontent.com/cloudformer/lambdavault/main/docs/architecture.svg)
28
+
29
+ The vault CLI, hvac and the Terraform vault provider are the clients — unchanged, only `VAULT_ADDR` points at
30
+ the Lambda. This package is the helper around a deployment:
31
+
32
+ ```bash
33
+ pip install lambdavault
34
+ lambdavault status # initialized / sealed / version / latency (address from terraform output)
35
+ eval "$(lambdavault output)" # export VAULT_ADDR for the vault CLI
36
+ vault operator init -recovery-shares=1 -recovery-threshold=1 # once
37
+ vault kv get kvv2/app
38
+ ```
39
+
40
+ Deploy the server from the [main repository](https://github.com/cloudformer/lambdavault) with Terraform.
41
+ Compatibility with a normal Vault: [REPORT.md](https://github.com/cloudformer/lambdavault/blob/main/tests/compat/REPORT.md).
@@ -0,0 +1,10 @@
1
+ README.md
2
+ pyproject.toml
3
+ lambdavault/__init__.py
4
+ lambdavault/__main__.py
5
+ lambdavault/cli.py
6
+ lambdavault.egg-info/PKG-INFO
7
+ lambdavault.egg-info/SOURCES.txt
8
+ lambdavault.egg-info/dependency_links.txt
9
+ lambdavault.egg-info/entry_points.txt
10
+ lambdavault.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ lambdavault = lambdavault.cli:main
@@ -0,0 +1 @@
1
+ lambdavault
@@ -0,0 +1,35 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "lambdavault"
7
+ version = "0.1.0"
8
+ description = "HashiCorp Vault on AWS Lambda + S3 + KMS, ≈ $0 when idle. The vault CLI, hvac and the Terraform vault provider talk to it unchanged; this package is the helper: status, output."
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = { text = "MIT" }
12
+ authors = [{ name = "Frank Zhang" }]
13
+ keywords = ["serverless", "aws", "lambda", "vault", "hashicorp-vault", "secrets", "kms"]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Programming Language :: Python :: 3",
19
+ "Topic :: Security",
20
+ ]
21
+ dependencies = [] # standard library only
22
+
23
+ [project.scripts]
24
+ lambdavault = "lambdavault.cli:main"
25
+
26
+ [project.urls]
27
+ Homepage = "https://github.com/cloudformer/lambdavault"
28
+ Repository = "https://github.com/cloudformer/lambdavault"
29
+ Deploy = "https://github.com/cloudformer/lambdavault#quick-start"
30
+ Compatibility = "https://github.com/cloudformer/lambdavault/blob/main/tests/compat/REPORT.md"
31
+ Changelog = "https://github.com/cloudformer/lambdavault/blob/main/CHANGELOG.md"
32
+ Issues = "https://github.com/cloudformer/lambdavault/issues"
33
+
34
+ [tool.setuptools]
35
+ packages = ["lambdavault"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+