{"id":7604,"library":"pyseto","title":"PySETO","description":"PySETO is a Python implementation of PASETO (Platform-Agnostic SEcurity TOkens) and PASERK (Platform-Agnostic Serialized Keys). It supports all PASETO versions (v1, v2, v3, and v4) and purposes (local and public), having passed all official tests. The library is currently at version 1.9.1 and maintains a regular release cadence.","status":"active","version":"1.9.1","language":"en","source_language":"en","source_url":"https://github.com/dajiaji/pyseto","tags":["security","token","paseto","encryption","signature","cryptography"],"install":[{"cmd":"pip install pyseto","lang":"bash","label":"Install PySETO"}],"dependencies":[{"reason":"Core cryptographic operations.","package":"cryptography","optional":false},{"reason":"Alternative cryptographic backend, often for performance or specific algorithms.","package":"pycryptodomex","optional":false}],"imports":[{"symbol":"pyseto","correct":"import pyseto"},{"note":"Key is a class within the pyseto package and needs to be imported explicitly.","wrong":"import Key","symbol":"Key","correct":"from pyseto import Key"}],"quickstart":{"code":"import os\nimport pyseto\nfrom pyseto import Key\n\n# --- Example for v4.public (Asymmetric Signature) ---\n# In a real application, keys should be loaded securely, e.g., from environment variables or a KMS.\n# For demonstration, we use hardcoded keys. DO NOT USE IN PRODUCTION AS IS.\n# These PEMs are for Ed25519 (v4.public)\nprivate_key_pem = os.environ.get(\n    'PSETO_V4_PRIVATE_KEY_PEM',\n    b\"\"\"-----BEGIN PRIVATE KEY-----\nMC4CAQAwBQYDK2VwBCIEILTL+0PfTOIQcn2VPkpxMwf6Gbt9n4UEFDjZ4RuUKjd0\n-----END PRIVATE KEY-----\n\"\"\").encode('utf-8')\n\npublic_key_pem = os.environ.get(\n    'PSETO_V4_PUBLIC_KEY_PEM',\n    b\"\"\"-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAHrnbu7wEfAP9cGBOAHHwmH4Wsot1ciXBHwBBXQ4gsaI=\n-----END PUBLIC KEY-----\n\"\"\").encode('utf-8')\n\n# 1. Create a private key for signing\nprivate_key = Key.new(version=4, purpose=\"public\", key=private_key_pem)\n\n# 2. Encode/Sign a PASETO token\npayload = {\"data\": \"this is a signed message\", \"user_id\": \"123\"}\nfooter = {\"kid\": \"v4-public-key-001\"}\ntoken = pyseto.encode(private_key, payload, footer=footer, serializer=pyseto.json_serializer)\nprint(f\"Generated Token: {token.decode()}\")\n\n# 3. Create a public key for verification\npublic_key = Key.new(version=4, purpose=\"public\", key=public_key_pem)\n\n# 4. Decode and verify the token\ndecoded_token = pyseto.decode(public_key, token, deserializer=pyseto.json_deserializer)\n\n# The payload and footer are accessible as dictionary-like objects if deserializer is used\nprint(f\"Decoded Payload: {decoded_token.payload}\")\nprint(f\"Decoded Footer: {decoded_token.footer}\")\n\nassert decoded_token.payload['data'] == \"this is a signed message\"\nassert decoded_token.footer['kid'] == \"v4-public-key-001\"\nprint(\"Token verified successfully!\")\n","lang":"python","description":"This quickstart demonstrates how to create and verify a PASETO token using the v4.public protocol for asymmetric signatures. It covers key generation from PEM bytes, encoding a payload with a footer, and decoding/verifying the token. It uses the built-in `json_serializer`/`json_deserializer` for dictionary payloads."},"warnings":[{"fix":"Upgrade PySETO to the latest version (1.8.0+ recommended) where dependency ranges are generally more flexible. If conflicts persist, try isolating dependency environments or manually resolving conflicts by specifying compatible versions of the conflicting libraries.","message":"Earlier versions of PySETO (e.g., <1.8.0) used strict version pinning for core dependencies like `cryptography` and `pycryptodomex`. This could lead to `ResolutionImpossible` errors during installation when combined with other libraries that had different `cryptography` requirements (e.g., `pyopenssl`).","severity":"breaking","affected_versions":"<1.8.0 (potentially up to 1.7.5)"},{"fix":"Migrate new token implementations to PASETO v3 or v4, which utilize modern and robust cryptographic algorithms like XChaCha20 and EdDSA.","message":"PASETO v2 is expected to be deprecated in the PASETO standard due to underlying cryptographic primitives. While PySETO supports v2, new development should ideally target PASETO versions 3 or 4 for future compatibility and enhanced security.","severity":"deprecated","affected_versions":"All versions supporting PASETO v2"},{"fix":"If custom `Paseto` behavior is required, explicitly create a `Paseto` instance: `my_paseto = Paseto(default_exp=3600)` and then use `my_paseto.encode()` and `my_paseto.decode()`.","message":"The top-level `pyseto.encode()` and `pyseto.decode()` functions are aliases to `encode()` and `decode()` methods of a global `Paseto` class instance created with default settings. If you intend to use custom `Paseto` instance settings (e.g., different default expiration times or `iat` inclusion), you must instantiate `Paseto` directly and call its methods, rather than relying on `pyseto.encode/decode`.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Try updating `pyseto` to the latest version. If the error persists, attempt to install specific versions of `pyopenssl` and `pyseto` that have compatible `cryptography` or `pycryptodomex` requirements. Consult the `setup.py` or `pyproject.toml` of both packages for their exact dependency specifications. Using a dedicated virtual environment for each project can prevent such conflicts.","cause":"Conflicting strict version requirements for a shared dependency (e.g., `cryptography` or `pycryptodomex`) between `pyseto` and another installed library (like `pyopenssl`).","error":"ERROR: Cannot install pyopenssl==X.Y.Z and pyseto==A.B.C because these package versions have conflicting dependencies."},{"fix":"Add `from pyseto import Key` at the top of your Python file where `Key` is used.","cause":"The `Key` class, used for creating PASETO keys, was not imported explicitly from the `pyseto` package.","error":"NameError: name 'Key' is not defined"},{"fix":"Ensure the correct symmetric key is used for decryption. Verify that the token itself has not been altered or corrupted. For `public` tokens, a `VerifyError` would typically indicate a signature mismatch.","cause":"This error occurs during `pyseto.decode()` when attempting to decrypt a `local` PASETO token if the provided symmetric key is incorrect, or if the token has been tampered with.","error":"pyseto.exceptions.DecryptError: Failed to decrypt the message"},{"fix":"Ensure the correct public key (corresponding to the private key used for signing) is provided for verification. Validate the integrity of the token and ensure it has not been modified after creation.","cause":"This error occurs during `pyseto.decode()` when attempting to verify a `public` PASETO token if the provided public key does not match the private key used for signing, or if the token's signature has been tampered with.","error":"pyseto.exceptions.VerifyError: Failed to verify the message"}]}