fujin-secrets-1password 0.16.0__py3-none-any.whl

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,95 @@
1
+ """1Password secret adapter for Fujin."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import subprocess
6
+ from concurrent.futures import ThreadPoolExecutor, as_completed
7
+ from contextlib import closing
8
+ from io import StringIO
9
+
10
+ from dotenv import dotenv_values
11
+ from fujin.config import SecretConfig
12
+ from fujin.errors import SecretResolutionError
13
+
14
+ __version__ = "0.1.0"
15
+
16
+
17
+ def onepassword(env_content: str, secret_config: SecretConfig) -> str:
18
+ """1Password secret adapter.
19
+
20
+ Retrieves secrets from 1Password using the `op` CLI.
21
+ Handles concurrent resolution of multiple secrets for performance.
22
+
23
+ Requires user to be pre-authenticated with `op` CLI.
24
+
25
+ Configuration:
26
+ adapter = "1password"
27
+
28
+ Usage pattern in env file:
29
+ SECRET_KEY=$op://personal/aws-key/password
30
+
31
+ Args:
32
+ env_content: Raw environment file content
33
+ secret_config: Secret configuration (unused for 1password)
34
+
35
+ Returns:
36
+ Resolved environment content with secrets replaced
37
+
38
+ Raises:
39
+ SecretResolutionError: If secret not found or CLI fails
40
+ """
41
+ # Parse env file
42
+ with closing(StringIO(env_content)) as buffer:
43
+ env_dict = dotenv_values(stream=buffer)
44
+
45
+ # Identify secrets (values starting with $)
46
+ secrets = {
47
+ key: value for key, value in env_dict.items() if value and value.startswith("$")
48
+ }
49
+
50
+ if not secrets:
51
+ return env_content
52
+
53
+ # Resolve secrets concurrently
54
+ resolved_secrets = {}
55
+ with ThreadPoolExecutor() as executor:
56
+ future_to_key = {
57
+ executor.submit(_read_secret, secret[1:]): key
58
+ for key, secret in secrets.items()
59
+ }
60
+
61
+ for future in as_completed(future_to_key):
62
+ key = future_to_key[future]
63
+ try:
64
+ resolved_secrets[key] = future.result()
65
+ except Exception as e:
66
+ raise SecretResolutionError(
67
+ f"Failed to retrieve secret for {key}: {e}",
68
+ adapter="1password",
69
+ key=key,
70
+ ) from e
71
+
72
+ # Merge resolved secrets back into env dict
73
+ env_dict.update(resolved_secrets)
74
+
75
+ return "\n".join(f'{key}="{value}"' for key, value in env_dict.items())
76
+
77
+
78
+ def _read_secret(name: str) -> str:
79
+ """Read a single secret from 1Password.
80
+
81
+ Args:
82
+ name: Secret reference (e.g., "op://personal/aws-key/password")
83
+
84
+ Returns:
85
+ Secret value
86
+
87
+ Raises:
88
+ SecretResolutionError: If secret not found
89
+ """
90
+ result = subprocess.run(["op", "read", name], capture_output=True, text=True)
91
+
92
+ if result.returncode != 0:
93
+ raise SecretResolutionError(result.stderr, adapter="1password", key=name)
94
+
95
+ return result.stdout.strip()
File without changes
@@ -0,0 +1,75 @@
1
+ Metadata-Version: 2.3
2
+ Name: fujin-secrets-1password
3
+ Version: 0.16.0
4
+ Summary: 1Password secret adapter for Fujin
5
+ Author: Tobi
6
+ Author-email: Tobi <tobidegnon@proton.me>
7
+ Classifier: Programming Language :: Python :: 3 :: Only
8
+ Classifier: Programming Language :: Python :: 3.10
9
+ Classifier: Programming Language :: Python :: 3.11
10
+ Classifier: Programming Language :: Python :: 3.12
11
+ Classifier: Programming Language :: Python :: 3.13
12
+ Classifier: Programming Language :: Python :: 3.14
13
+ Requires-Dist: fujin-cli>=0.16
14
+ Requires-Dist: python-dotenv>=1.0.1
15
+ Requires-Python: >=3.10
16
+ Project-URL: Homepage, https://github.com/Tobi-De/fujin
17
+ Project-URL: Issues, https://github.com/Tobi-De/fujin/issues
18
+ Project-URL: Source, https://github.com/Tobi-De/fujin
19
+ Description-Content-Type: text/markdown
20
+
21
+ # Fujin Secrets - 1Password
22
+
23
+ 1Password secret adapter for Fujin deployment tool.
24
+
25
+ ## Installation
26
+
27
+ ```bash
28
+ pip install fujin-secrets-1password
29
+ ```
30
+
31
+ Or with uv:
32
+
33
+ ```bash
34
+ uv pip install fujin-secrets-1password
35
+ ```
36
+
37
+ ## Prerequisites
38
+
39
+ Download and install the [1Password CLI](https://developer.1password.com/docs/cli/) and sign in to your account.
40
+
41
+ You need to be actively signed in for Fujin to work with 1Password.
42
+
43
+ ## Configuration
44
+
45
+ Add the following to your `fujin.toml` file:
46
+
47
+ ```toml
48
+ [secrets]
49
+ adapter = "1password"
50
+ ```
51
+
52
+ ## Usage
53
+
54
+ In your environment file (`.env` or configured via `envfile` in `fujin.toml`), use 1Password secret references:
55
+
56
+ ```env
57
+ DEBUG=False
58
+ AWS_ACCESS_KEY_ID=$op://personal/aws-access-key-id/password
59
+ AWS_SECRET_ACCESS_KEY=$op://personal/aws-secret-access-key/password
60
+ ```
61
+
62
+ The secret reference format is: `$op://vault/item/field`
63
+
64
+ ## How it Works
65
+
66
+ The adapter:
67
+ 1. Uses the existing 1Password CLI session (requires you to be signed in)
68
+ 2. Resolves all secrets concurrently using `op read <reference>`
69
+ 3. Returns the resolved environment variables
70
+
71
+ ## Related
72
+
73
+ - [Fujin Documentation](https://github.com/Tobi-De/fujin)
74
+ - [1Password CLI Documentation](https://developer.1password.com/docs/cli/)
75
+ - [1Password Secret References](https://developer.1password.com/docs/cli/secret-references/)
@@ -0,0 +1,6 @@
1
+ fujin_secrets_1password/__init__.py,sha256=E8py2UCRsZ86qZS2IzmsHEDu4xAJ7keXwdSpPZcWbyY,2716
2
+ fujin_secrets_1password/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ fujin_secrets_1password-0.16.0.dist-info/WHEEL,sha256=ZyFSCYkV2BrxH6-HRVRg3R9Fo7MALzer9KiPYqNxSbo,79
4
+ fujin_secrets_1password-0.16.0.dist-info/entry_points.txt,sha256=dI0TfmWiIt2HEZw_CFWTrC8hxunE2sHkSwmd9HhEgcM,65
5
+ fujin_secrets_1password-0.16.0.dist-info/METADATA,sha256=czGdxi-yAMKOCqvsmyP6ozEJsT1r1lKCHnikSHHHJ-0,2091
6
+ fujin_secrets_1password-0.16.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: uv 0.9.18
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,3 @@
1
+ [fujin.secrets]
2
+ 1password = fujin_secrets_1password:onepassword
3
+