Page MenuHomeDevCentral

D3703.diff
No OneTemporary

D3703.diff

diff --git a/.gitignore b/.gitignore
--- a/.gitignore
+++ b/.gitignore
@@ -8,3 +8,6 @@
tools/rhyne-wyse/apicache/
*.lwp
throttle.ctrl
+
+# Sphinx
+_build/
diff --git a/tools/secretsmith/docs/Makefile b/tools/secretsmith/docs/Makefile
new file mode 100644
--- /dev/null
+++ b/tools/secretsmith/docs/Makefile
@@ -0,0 +1,19 @@
+# -------------------------------------------------------------
+# Rhyne-Wyse :: Sphinx documentation
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Project: Nasqueron
+# License: Trivial work, not eligible to copyright
+# -------------------------------------------------------------
+
+SPHINXOPTS ?=
+SPHINXBUILD ?= sphinx-build
+SOURCEDIR = .
+BUILDDIR = _build
+
+help:
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+%: Makefile
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/tools/secretsmith/docs/conf.py b/tools/secretsmith/docs/conf.py
new file mode 100644
--- /dev/null
+++ b/tools/secretsmith/docs/conf.py
@@ -0,0 +1,31 @@
+# -------------------------------------------------------------
+# Rhyne-Wyse :: Sphinx documentation
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Project: Nasqueron
+# License: Trivial work, not eligible to copyright
+# Reference: https://www.sphinx-doc.org/en/master/usage/configuration.html
+# -------------------------------------------------------------
+
+# -------------------------------------------------------------
+# Project information
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+project = "secretsmith"
+copyright = "2025, Nasqueron | Released under CC-BY 4.0 license."
+author = "Sébastien Santoro aka Dereckson"
+
+# -------------------------------------------------------------
+# General configuration
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+extensions = []
+
+templates_path = ["_templates"]
+exclude_patterns = ["_build"]
+
+# -------------------------------------------------------------
+# HTML output
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+html_theme = "haiku"
+html_static_path = ["_static"]
diff --git a/tools/secretsmith/docs/connect.rst b/tools/secretsmith/docs/connect.rst
new file mode 100644
--- /dev/null
+++ b/tools/secretsmith/docs/connect.rst
@@ -0,0 +1,87 @@
+===========================
+Connect to Vault or OpenBao
+===========================
+
+Code is minimalist
+==================
+
+As everything happen in the application configuration file,
+your code needs two things:
+
+- get the path of your configuration file
+- invoke secretsmith.login()
+
+.. code-block:: python
+
+ import secretsmith
+
+ VAULT_CONFIG_PATH = "/path/to/config.yaml"
+
+ vault_client = secretsmith.login(config_path=VAULT_CONFIG_PATH)
+
+You'll then get a hvac.Client object and can call any hvac method on it.
+
+Configuration file
+==================
+
+Introduction
+------------
+
+Secretsmith uses a YAML configuration file to determine the login parameters:
+
+.. code-block:: yaml
+
+ vault:
+ server:
+ url: https://127.0.0.1:8200
+ auth:
+ token: hvs.000000000000000000000000
+
+When using AppRole, the configuration file will look like:
+
+.. code-block:: yaml
+
+ vault:
+ server:
+ url: https://127.0.0.1:8200
+ verify: /path/to/ca.pem
+ auth:
+ method: approle
+ role_id: e5a7b66e-5d08-da9c-7075-71984634b882
+ secret_id: 841771dc-11c9-bbc7-bcac-6a3945a69cd9
+
+The format is based on the Vault execution module for SaltStack.
+
+Global parameters
+-----------------
+
+The following parameters are supported:
+
+- ``server`` — a block to specify the Vault or OpenBao server parameters
+
+ - ``url`` — the URL
+ - ``verify`` — the path to a CA certificate to verify the server's certificate
+ - ``namespace`` — the namespace to use (by default, will follow environment)
+
+- ``auth`` — a block to specify the authentication method and parameters
+
+ - ``method`` — what authentication backend to use, by default ``token``
+
+Additional parameters are supported in the ``auth`` block depending
+on the authentication method.
+
+Token authentication method
+----------------------------
+
+When the method is ``token``, the following additional parameters are supported:
+
+- ``token`` — the token to use
+- ``token_file`` — alternatively, the path to a file containing the token
+
+AppRole authentication method
+-----------------------------
+
+When the method is ``approle``, the following additional parameters are supported:
+
+- ``role_id`` — the AppRole role ID (required)
+- ``secret_id`` — the AppRole secret ID (optional)
diff --git a/tools/secretsmith/docs/getting-started.rst b/tools/secretsmith/docs/getting-started.rst
new file mode 100644
--- /dev/null
+++ b/tools/secretsmith/docs/getting-started.rst
@@ -0,0 +1,36 @@
+================================
+Getting started with secretsmith
+================================
+
+Installation
+============
+The secretsmith package is available on PyPI:
+
+.. code-block:: shell
+
+ $ pip install secretsmith
+
+We suggest you add the package in a requirements.txt file:
+
+.. code-block:: text
+
+ secretsmith~=0.1.0
+
+How to use in code?
+===================
+
+Call ``secretsmith.login()`` with the path to the configuration file:
+
+.. code-block:: python
+
+ import secretsmith
+
+ VAULT_CONFIG_PATH = "/path/to/config.yaml"
+
+ vault_client = secretsmith.login(config_path=VAULT_CONFIG_PATH)
+
+Then, you can use the client as a hvac library Vault client.
+
+We provide helper methods for common tasks, but you can also directly use hvac.
+
+See :doc:`connect` for the configuration file format.
diff --git a/tools/secretsmith/docs/index.rst b/tools/secretsmith/docs/index.rst
new file mode 100644
--- /dev/null
+++ b/tools/secretsmith/docs/index.rst
@@ -0,0 +1,33 @@
+.. secretsmith documentation main file, created by
+ sphinx-quickstart on Sat Sep 20 20:04:12 2025.
+
+secretsmith
+===========
+
+Introduction
+------------
+
+The secretsmith package is a high-level wrapper on the top of hvac
+to connect to a Vault or OpenBao server.
+
+secretsmith has been written to avoid to repeat boilerplate code
+about connections details like authentication method or namespace.
+
+One of the strength of secretsmith is to allow the Vault connection
+to be configured by a YAML file instead of having to take decisions
+in code, and repeat local configuration parsing in each project.
+
+Contents
+--------
+
+.. toctree::
+ :maxdepth: 3
+
+ getting-started
+ connect
+ kv2
+
+Appendices
+----------
+
+* :ref:`search`
diff --git a/tools/secretsmith/docs/kv2.rst b/tools/secretsmith/docs/kv2.rst
new file mode 100644
--- /dev/null
+++ b/tools/secretsmith/docs/kv2.rst
@@ -0,0 +1,107 @@
+========================================
+Interact with key/value v2 secret engine
+========================================
+
+Querying secrets
+================
+
+Secrets are usually stored in a kv2 secret engine.
+
+As hvac syntax can be particularly verbose for those operations,
+secretsmith also provides helper methods for more common use cases.
+
+All examples assume you have already obtained a logged-in client with
+``secretsmith.login()`` and then import the helpers::
+
+ from secretsmith.vault import secrets
+
+The examples assume you want to query in the ``secret`` mounting point the ``app/db`` secret path.
+Replace ``secret`` by your own kv2 mounting point when different.
+
+read_secret
+-----------
+
+**Goal**:
+Read a secret from kv2 and return only the secret data as a dictionary.
+This is the simplest helper to fetch all key/value pairs stored at a path.
+
+**Example**::
+
+ secret = secrets.read_secret(vault_client, "secret", "app/db")
+ print(secret["username"])
+
+read_secret_with_metadata
+-------------------------
+
+**Goal**:
+Read a secret from kv2 and return **both the data and the metadata**.
+Metadata includes information such as version number, timestamps, etc.
+
+**Example**::
+
+ data, metadata = secrets.read_secret_with_metadata(vault_client, "secret", "app/db")
+ print("User:", data["username"])
+ print("Secret created at:", metadata["created_time"])
+ print("Secret version:", metadata["version"])
+
+If you've custom metadata, those are available in ``metadata["custom_metadata"]``.
+
+read_secret_with_custom_metadata
+--------------------------------
+
+**Goal**:
+Like ``read_secret_with_metadata``, but also merges **custom metadata**
+fields directly into the returned metadata dictionary. This is useful if
+you add annotations to your secrets.
+
+**Example**::
+
+ data, metadata = secrets.read_secret_with_custom_metadata(vault_client, "secret", "app/db")
+ print("User:", data["username"])
+ if "owner" in metadata:
+ print("Secret owner:", metadata["owner"])
+
+get_username
+------------
+
+**Goal**:
+Return the ``username`` field from a secret, raising an error if it is
+missing. This is a straightforward design choice for cases where you
+don't want to deal with a full dictionary of values.
+
+**Example**::
+
+ user = secrets.get_username(vault_client, "secret", "app/db")
+ print("Username:", user)
+
+get_password
+------------
+
+**Goal**:
+Return the ``password`` field from a secret, raising an error if it is
+missing.
+
+**Example**::
+
+ password = secrets.get_password(vault_client, "secret", "app/db")
+
+get_field
+---------
+
+**Goal**:
+Return a specific field from a secret. This is the generic helper that
+``get_username`` and ``get_password`` build upon. Raises a ``ValueError``
+if the requested field does not exist.
+
+**Use case**:
+When you use a secret to store API keys and tokens, chances are you only
+have one field, to query only this field as a string is straightforward.
+
+**Example**::
+
+ api_key = secrets.get_field(vault_client, "secret", "app/service", "api-key")
+
+hvac
+====
+
+You can still directly use hvac. The helper methods are only provided as sugar syntax.

File Metadata

Mime Type
text/plain
Expires
Mon, Sep 22, 18:06 (22 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3006296
Default Alt Text
D3703.diff (9 KB)

Event Timeline