updated docs strings and added README.md
This commit is contained in:
@@ -1,10 +1,8 @@
|
||||
"""
|
||||
# Summary
|
||||
|
||||
Credential persistence interfaces and implementations for Mail Intake.
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
This package defines the abstractions and concrete implementations used
|
||||
to persist authentication credentials across Mail Intake components.
|
||||
|
||||
@@ -14,20 +12,21 @@ credential acquisition, validation, and refresh, while implementations
|
||||
within this package are responsible solely for storage and retrieval.
|
||||
|
||||
The package provides:
|
||||
- A generic ``CredentialStore`` abstraction defining the persistence contract
|
||||
- Local filesystem–based storage for development and single-node use
|
||||
- Distributed, Redis-backed storage for production and scaled deployments
|
||||
|
||||
- A generic `CredentialStore` abstraction defining the persistence contract.
|
||||
- Local filesystem–based storage for development and single-node use.
|
||||
- Distributed, Redis-backed storage for production and scaled deployments.
|
||||
|
||||
Credential lifecycle management, interpretation, and security policy
|
||||
decisions remain the responsibility of authentication providers.
|
||||
|
||||
---
|
||||
|
||||
## Public API
|
||||
# Public API
|
||||
|
||||
CredentialStore
|
||||
PickleCredentialStore
|
||||
RedisCredentialStore
|
||||
- `CredentialStore`
|
||||
- `PickleCredentialStore`
|
||||
- `RedisCredentialStore`
|
||||
|
||||
---
|
||||
"""
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
"""
|
||||
# Summary
|
||||
|
||||
Local filesystem–based credential persistence for Mail Intake.
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
This module provides a file-backed implementation of the
|
||||
``CredentialStore`` abstraction using Python's ``pickle`` module.
|
||||
`CredentialStore` abstraction using Python's `pickle` module.
|
||||
|
||||
The pickle-based credential store is intended for local development,
|
||||
The `pickle`-based credential store is intended for local development,
|
||||
single-node deployments, and controlled environments where credentials
|
||||
do not need to be shared across processes or machines.
|
||||
|
||||
Due to the security and portability risks associated with pickle-based
|
||||
Due to the security and portability risks associated with `pickle`-based
|
||||
serialization, this implementation is not suitable for distributed or
|
||||
untrusted environments.
|
||||
"""
|
||||
@@ -36,13 +34,14 @@ class PickleCredentialStore(CredentialStore[T]):
|
||||
Notes:
|
||||
**Guarantees:**
|
||||
|
||||
- Stores credentials on the local filesystem
|
||||
- Uses pickle for serialization and deserialization
|
||||
- Does not provide encryption, locking, or concurrency guarantees
|
||||
- Stores credentials on the local filesystem.
|
||||
- Uses `pickle` for serialization and deserialization.
|
||||
- Does not provide encryption, locking, or concurrency guarantees.
|
||||
|
||||
**Constraints:**
|
||||
|
||||
- Credential lifecycle management, validation, and refresh logic are explicitly out of scope for this class
|
||||
|
||||
- Credential lifecycle management, validation, and refresh logic are
|
||||
explicitly out of scope for this class.
|
||||
"""
|
||||
|
||||
def __init__(self, path: str):
|
||||
@@ -62,14 +61,16 @@ class PickleCredentialStore(CredentialStore[T]):
|
||||
|
||||
Returns:
|
||||
Optional[T]:
|
||||
An instance of type ``T`` if credentials are present and
|
||||
successfully deserialized; otherwise ``None``.
|
||||
An instance of type `T` if credentials are present and
|
||||
successfully deserialized; otherwise `None`.
|
||||
|
||||
Notes:
|
||||
**Guarantees:**
|
||||
|
||||
- If the credential file does not exist or cannot be successfully deserialized, this method returns ``None``
|
||||
- The store does not attempt to validate or interpret the returned credentials
|
||||
- If the credential file does not exist or cannot be successfully
|
||||
deserialized, this method returns `None`.
|
||||
- The store does not attempt to validate or interpret the
|
||||
returned credentials.
|
||||
"""
|
||||
try:
|
||||
with open(self.path, "rb") as fh:
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
"""
|
||||
# Summary
|
||||
|
||||
Redis-backed credential persistence for Mail Intake.
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
This module provides a Redis-based implementation of the
|
||||
``CredentialStore`` abstraction, enabling credential persistence
|
||||
`CredentialStore` abstraction, enabling credential persistence
|
||||
across distributed and horizontally scaled deployments.
|
||||
|
||||
The Redis credential store is designed for environments where
|
||||
@@ -15,10 +13,11 @@ processes, containers, or nodes, such as container orchestration
|
||||
platforms and microservice architectures.
|
||||
|
||||
Key characteristics:
|
||||
- Distributed-safe, shared storage using Redis
|
||||
- Explicit, caller-defined serialization and deserialization
|
||||
- No reliance on unsafe mechanisms such as pickle
|
||||
- Optional time-to-live (TTL) support for automatic credential expiry
|
||||
|
||||
- Distributed-safe, shared storage using Redis.
|
||||
- Explicit, caller-defined serialization and deserialization.
|
||||
- No reliance on unsafe mechanisms such as `pickle`.
|
||||
- Optional time-to-live (TTL) support for automatic credential expiry.
|
||||
|
||||
This module is responsible solely for persistence concerns.
|
||||
Credential validation, refresh, rotation, and acquisition remain the
|
||||
@@ -35,7 +34,7 @@ T = TypeVar("T")
|
||||
|
||||
class RedisCredentialStore(CredentialStore[T]):
|
||||
"""
|
||||
Redis-backed implementation of ``CredentialStore``.
|
||||
Redis-backed implementation of `CredentialStore`.
|
||||
|
||||
This store persists credentials in Redis and is suitable for
|
||||
distributed and horizontally scaled deployments where credentials
|
||||
@@ -44,13 +43,16 @@ class RedisCredentialStore(CredentialStore[T]):
|
||||
Notes:
|
||||
**Responsibilities:**
|
||||
|
||||
- This class is responsible only for persistence and retrieval
|
||||
- It does not interpret, validate, refresh, or otherwise manage the lifecycle of the credentials being stored
|
||||
- This class is responsible only for persistence and retrieval.
|
||||
- It does not interpret, validate, refresh, or otherwise manage the
|
||||
lifecycle of the credentials being stored.
|
||||
|
||||
**Guarantees:**
|
||||
|
||||
- The store is intentionally generic and delegates all serialization concerns to caller-provided functions
|
||||
- This avoids unsafe mechanisms such as pickle and allows credential formats to be explicitly controlled and audited
|
||||
- The store is intentionally generic and delegates all serialization
|
||||
concerns to caller-provided functions.
|
||||
- This avoids unsafe mechanisms such as `pickle` and allows
|
||||
credential formats to be explicitly controlled and audited.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
@@ -92,14 +94,18 @@ class RedisCredentialStore(CredentialStore[T]):
|
||||
|
||||
Returns:
|
||||
Optional[T]:
|
||||
An instance of type ``T`` if credentials are present and
|
||||
successfully deserialized; otherwise ``None``.
|
||||
An instance of type `T` if credentials are present and
|
||||
successfully deserialized; otherwise `None`.
|
||||
|
||||
Notes:
|
||||
**Guarantees:**
|
||||
|
||||
- If no value exists for the configured key, or if the stored payload cannot be successfully deserialized, this method returns ``None``
|
||||
- The store does not attempt to validate the returned credentials or determine whether they are expired or otherwise usable
|
||||
- If no value exists for the configured key, or if the stored
|
||||
payload cannot be successfully deserialized, this method
|
||||
returns `None`.
|
||||
- The store does not attempt to validate the returned
|
||||
credentials or determine whether they are expired or
|
||||
otherwise usable.
|
||||
"""
|
||||
raw = self.redis.get(self.key)
|
||||
if not raw:
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
"""
|
||||
# Summary
|
||||
|
||||
Credential persistence abstractions for Mail Intake.
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
This module defines the generic persistence contract used to store and
|
||||
retrieve authentication credentials across Mail Intake components.
|
||||
|
||||
The ``CredentialStore`` abstraction establishes a strict separation
|
||||
The `CredentialStore` abstraction establishes a strict separation
|
||||
between credential *lifecycle management* and credential *storage*.
|
||||
Authentication providers are responsible for acquiring, validating,
|
||||
refreshing, and revoking credentials, while concrete store
|
||||
@@ -30,21 +28,23 @@ T = TypeVar("T")
|
||||
|
||||
class CredentialStore(ABC, Generic[T]):
|
||||
"""
|
||||
Abstract base class defining a generic persistence interface for
|
||||
authentication credentials.
|
||||
Abstract base class defining a generic persistence interface.
|
||||
|
||||
Used for authentication credentials across different backends.
|
||||
|
||||
Notes:
|
||||
**Responsibilities:**
|
||||
|
||||
- Provide persistent storage separating life-cycle management from storage mechanics
|
||||
- Keep implementation focused only on persistence
|
||||
|
||||
- Provide persistent storage separating life-cycle management from
|
||||
storage mechanics.
|
||||
- Keep implementation focused only on persistence.
|
||||
|
||||
**Constraints:**
|
||||
|
||||
|
||||
- The store is intentionally agnostic to:
|
||||
- The concrete credential type being stored
|
||||
- The serialization format used to persist credentials
|
||||
- The underlying storage backend or durability guarantees
|
||||
- The concrete credential type being stored.
|
||||
- The serialization format used to persist credentials.
|
||||
- The underlying storage backend or durability guarantees.
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
@@ -54,14 +54,17 @@ class CredentialStore(ABC, Generic[T]):
|
||||
|
||||
Returns:
|
||||
Optional[T]:
|
||||
An instance of type ``T`` if credentials are available and
|
||||
loadable; otherwise ``None``.
|
||||
An instance of type `T` if credentials are available and
|
||||
loadable; otherwise `None`.
|
||||
|
||||
Notes:
|
||||
**Guarantees:**
|
||||
|
||||
- Implementations should return ``None`` when no credentials are present or when stored credentials cannot be successfully decoded or deserialized
|
||||
- The store must not attempt to validate, refresh, or otherwise interpret the returned credentials
|
||||
- Implementations should return `None` when no credentials are
|
||||
present or when stored credentials cannot be successfully
|
||||
decoded or deserialized.
|
||||
- The store must not attempt to validate, refresh, or otherwise
|
||||
interpret the returned credentials.
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
|
||||
Reference in New Issue
Block a user