Skip to main content

A lightweight and extensible Single Sign-On (SSO) authentication library for Python.

Project description

more-sso-auth — Lightweight SSO for Python

A small, easy-to-use Single Sign-On (SSO) helper for Python apps and AWS Lambda.

What it gives you

  • RS256 JWT validation using a public key fetched from a URL.
  • In-memory caching for public keys (no constant network calls).
  • A header-based decorator @auth_required for quick route protection.
  • A root_auth_required decorator suitable for Lambda handlers.
  • Programmatic and environment-variable configuration.
  • An extensible permission system via BasePermission so you can write custom rules.

Quick start (3 minutes)

  1. Install
pip install more-sso-auth
  1. Configure (either method)

Programmatic

from more_sso import init_sso_config

init_sso_config(
    public_key_uri="https://auth.more.in/public_key",
    audience="my-service"
)

Environment variables

export PUBLIC_KEY_URI="https://auth.more.in/public_key"
export AUDIENCE="my-service"
  1. Protect a function
from more_sso import auth_required

@auth_required(permission="pma.role", value="admin")
def my_func(event, *args, **kwargs):
    user = event["requestContext"]["user"]
    return {"ok": True}

The decorator will validate the bearer JWT from the Authorization header and inject the decoded payload consistently into event["requestContext"]["user"].


Core Concepts

Token validation

Use validate_token(token) to validate a JWT programmatically. It raises JWTValidationError on invalid tokens.

from more_sso import validate_token, JWTValidationError
try:
    user = validate_token(token)
except JWTValidationError as e:
    # handle unauthenticated
    print("Invalid token:", str(e))

validate_token performs usual checks: signature (RS256), audience (the AUDIENCE you configured), and token expiry.

Decorators

  • @auth_required(...) — decorator for fine-grained route enforcement. It supports either a simple permission check or a custom permission class. After validation it injects the decoded token into event["requestContext"]["user"].
  • @root_auth_required — a simple decorator for Lambda handlers that enforces authentication at the top level and injects the decoded user into event["requestContext"]["user"]. If authentication fails, the decorator returns a 401 response (for AWS Lambda-style handlers).

Example: root-level Lambda

from more_sso import root_auth_required

@root_auth_required
def lambda_handler(event, context):
    user = event["requestContext"]["user"]
    return {"statusCode": 200, "body": f"Hello {user['sub']}"}

Permissions

There are two ways to enforce authorization with auth_required:

  1. Simple claim check — pass permission and value.

    • permission is a dotted path into the decoded JWT payload (for example: pma.role will look up user["pma"]["role"]).
    • value is the expected value.
@auth_required(permission="my_app.role", value="admin")
def handler(event, *args, **kwargs):
    user = event["requestContext"].get("user", {})
    # ...
  1. Custom permission class — extend BasePermission and implement has_access().
from more_sso import BasePermission, auth_required, AccessDeniedError

class CustomPermission(BasePermission):
    def has_access(self) -> bool:
        # example: allow only admins
        return self.user.get("role") == "admin"

@auth_required(permission_class=CustomPermission)
def admin_only(event, *args, **kwargs):
    return {"ok": "admin access granted"}

# caller example
try:
    admin_only()
except AccessDeniedError:
    # return 403
    pass

Behavior: when permission check fails the decorator raises AccessDeniedError (or returns an appropriate 403 when used as a top-level Lambda decorator if configured that way).


AWS Lambda patterns

Top-level enforcement (recommended for simple APIs):

from more_sso import root_auth_required

@root_auth_required
def lambda_handler(event, context):
    user = event["requestContext"]["user"]
    # authorized
    return {"statusCode": 200, "body": "ok"}

Function-level enforcement (fine-grained):

from more_sso import auth_required, AccessDeniedError

@auth_required(permission="my_app.role", value="admin")
def admin_action(event, *args, **kwargs):
    return {"ok": True}

def lambda_handler(event, context):
    try:
        return admin_action(event)
    except AccessDeniedError:
        return {"statusCode": 403, "body": "Access denied"}

Note: Both auth_required and root_auth_required inject the decoded token consistently into event["requestContext"]["user"].


API reference (quick)

  • init_sso_config(public_key_uri: str, audience: str) — initialize the library programmatically.
  • validate_token(token: str) -> dict — validate token and return decoded payload. Raises JWTValidationError on failure.
  • auth_required(permission: str = None, value: Any = None, permission_class: Type[BasePermission] = None) — decorator to protect functions. Injects user into event["requestContext"]["user"].
  • root_auth_required — decorator for Lambda handlers.
  • BasePermission — extend this and implement has_access(self) -> bool for custom checks. The class has access to self.user.
  • JWTValidationError — raised for invalid JWTs.
  • AccessDeniedError — raised when permission checks fail.

Security notes

  • Always validate aud (audience) and exp (expiry). more-sso-auth checks these by default when configured.
  • Rotate keys at the Identity Provider (IdP) and ensure the IdP exposes the new public key at the configured PUBLIC_KEY_URI.

Troubleshooting & FAQ

Q: Where does the library read the token from? A: From the Authorization: Bearer <token> header in incoming requests.

Q: How do I check complex permissions (lists, nested claims)? A: Use a BasePermission subclass and implement has_access() — you have full access to the decoded payload and can evaluate arbitrarily complex logic.


Contributing & License

  • Source: https://github.com/more-retail/moresso
  • License: MIT

Contributions are welcome via PRs. Please follow the repository's contribution guidelines for tests and code style.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

more_sso_auth-1.2.5.tar.gz (6.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

more_sso_auth-1.2.5-py3-none-any.whl (8.4 kB view details)

Uploaded Python 3

File details

Details for the file more_sso_auth-1.2.5.tar.gz.

File metadata

  • Download URL: more_sso_auth-1.2.5.tar.gz
  • Upload date:
  • Size: 6.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for more_sso_auth-1.2.5.tar.gz
Algorithm Hash digest
SHA256 42552d956bae897d10c31fa01e0a6e2779d4eb1e70dfebb6b0b237ecdd3ca5bb
MD5 6aee61047e5fb58afe00be065205ec90
BLAKE2b-256 155a5df7389a1def34d15e50dedfee40287fefd9410e7f0e4483689c31e33f56

See more details on using hashes here.

Provenance

The following attestation bundles were made for more_sso_auth-1.2.5.tar.gz:

Publisher: workflow.yml on more-retail/moresso

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file more_sso_auth-1.2.5-py3-none-any.whl.

File metadata

  • Download URL: more_sso_auth-1.2.5-py3-none-any.whl
  • Upload date:
  • Size: 8.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for more_sso_auth-1.2.5-py3-none-any.whl
Algorithm Hash digest
SHA256 f316e64d4268e176f78186a94211d93b980c8f96f8a3da5717085ca1b3cb7a5e
MD5 9abff567a29aba5e04142e20dc883856
BLAKE2b-256 0786177719358f2dd6590f5615742951224f3541b3d062f9992a6dbde34f278f

See more details on using hashes here.

Provenance

The following attestation bundles were made for more_sso_auth-1.2.5-py3-none-any.whl:

Publisher: workflow.yml on more-retail/moresso

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page