{"id":8766,"library":"vonage-jwt","title":"Vonage JWT","description":"The `vonage-jwt` package provides tooling for generating JSON Web Tokens (JWTs) for Vonage APIs in Python. It is primarily utilized by the Vonage Python SDK for authentication but can also be used as a standalone library. The current version is 1.1.5, with its latest release uploaded on November 29, 2024, indicating a moderate release cadence.","status":"active","version":"1.1.5","language":"en","source_language":"en","source_url":"https://github.com/Vonage/vonage-python-jwt","tags":["Vonage","JWT","authentication","security","API","python-jose"],"install":[{"cmd":"pip install vonage-jwt","lang":"bash","label":"Install vonage-jwt"}],"dependencies":[{"reason":"Required for JOSE (JSON Object Signing and Encryption) operations, including JWT encoding and decoding.","package":"python-jose","optional":false},{"reason":"Provides cryptographic primitives used for signing JWTs.","package":"cryptography","optional":false}],"imports":[{"symbol":"JwtClient","correct":"from vonage_jwt import JwtClient"}],"quickstart":{"code":"import os\nfrom vonage_jwt import JwtClient\n\n# It's recommended to load these from environment variables or a secure configuration.\nVONAGE_APPLICATION_ID = os.environ.get('VONAGE_APPLICATION_ID', 'YOUR_APPLICATION_ID')\nVONAGE_PRIVATE_KEY_PATH = os.environ.get('VONAGE_PRIVATE_KEY_PATH', './private.key') # Path to your private.key file\n\nprivate_key_content = None\ntry:\n    with open(VONAGE_PRIVATE_KEY_PATH, 'r') as f:\n        private_key_content = f.read()\nexcept FileNotFoundError:\n    print(f\"Error: Private key file not found at {VONAGE_PRIVATE_KEY_PATH}.\")\n    print(\"Please ensure the path is correct or the file exists.\")\n    # In a real application, you might want to raise an exception or handle this more robustly.\n\nif VONAGE_APPLICATION_ID != 'YOUR_APPLICATION_ID' and private_key_content:\n    try:\n        jwt_client = JwtClient(VONAGE_APPLICATION_ID, private_key_content)\n        jwt_token = jwt_client.generate_application_jwt()\n        print(f\"Successfully generated JWT: {jwt_token}\")\n    except Exception as e:\n        print(f\"Error generating JWT: {e}\")\nelse:\n    print(\"Please set VONAGE_APPLICATION_ID and ensure VONAGE_PRIVATE_KEY_PATH points to a valid private key file.\")","lang":"python","description":"This quickstart demonstrates how to initialize the `JwtClient` with your Vonage Application ID and private key, then generate an application-level JWT. It expects the application ID and private key path to be provided via environment variables for security. The private key content is read from the specified file path. Replace placeholders or set environment variables before running."},"warnings":[{"fix":"Ensure all JWT generation occurs server-side, and only the generated token is sent to the client if needed.","message":"JWTs should always be generated on the backend. Exposing the private key or generation logic on the frontend is a significant security risk.","severity":"gotcha","affected_versions":"All"},{"fix":"Verify that the `application_id` matches your Vonage application and the `private_key` is the correct, untampered key associated with it.","message":"Incorrect `application_id` or `private_key` will lead to authentication failures (e.g., '401 Unauthorized', 'Invalid signature', or 'Issuer not found').","severity":"breaking","affected_versions":"All"},{"fix":"Ensure your server's system clock is synchronized with NTP. Validate JWTs for correct `iat`, `nbf` (not before), and `exp` (expiration) claims, typically handled by the library.","message":"JWTs are time-sensitive. If your server's clock is not synchronized or the 'iat' (issued at time) claim is in the future, tokens may be prematurely deemed expired, resulting in errors like 'JWT has expired' or '401 Unauthorized'.","severity":"gotcha","affected_versions":"All"},{"fix":"After generating new keys, explicitly save the application settings in the Vonage Dashboard.","message":"When regenerating public/private key pairs in the Vonage Dashboard, always click 'Save changes' for the application. Failing to do so can lead to 'Invalid token' errors as the old keys remain active or the new ones aren't registered.","severity":"gotcha","affected_versions":"All"},{"fix":"Refer to the specific API documentation to confirm the expected value for the 'sub' claim. If 'sub' is required, ensure it is populated with the username.","message":"For certain Vonage APIs (e.g., some Client SDK sessions), the 'sub' (subject) claim in the JWT must be the *username* and not the user ID. Using the wrong identifier can cause session timeouts.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Double-check your `application_id` and `private_key` for accuracy. Verify the private key file exists and its content is correct. Ensure the JWT hasn't expired prematurely due to clock skew.","cause":"The generated JWT is invalid, expired, or signed with an incorrect private key/application ID.","error":"401 Unauthorized"},{"fix":"Confirm you are using the correct `private.key` file for the specified `application_id`. Ensure there are no extra spaces or line breaks when reading the private key content.","cause":"The JWT was signed with a private key that does not match the public key registered with your Vonage application, or the private key content is malformed.","error":"Invalid signature"},{"fix":"Generate a new JWT. Ensure your server's time is synchronized. Review the JWT's claims (`iat`, `nbf`, `exp`) using a tool like jwt.io to confirm their validity.","cause":"The `exp` (expiration) claim in the JWT indicates it is no longer valid, or the `iat` (issued at time) claim is set in the future relative to the API server's time.","error":"JWT has expired"},{"fix":"Verify the `VONAGE_PRIVATE_KEY_PATH` environment variable or direct path in your code points to the actual location of your `private.key` file. Ensure the script has read permissions for the file.","cause":"The path provided for the private key file is incorrect or the file does not exist at the specified location.","error":"FileNotFoundError: [Errno 2] No such file or directory: 'private.key'"}]}