{"id":9995,"library":"oathtool","title":"OATHTool","description":"oathtool is a command-line tool and Python library for generating one-time passwords, supporting both HOTP (HMAC-based) and TOTP (Time-based) algorithms. The current version is 2.4.0, and it maintains a stable, albeit infrequent, release schedule, focusing on reliability and security.","status":"active","version":"2.4.0","language":"python","source_language":"en","source_url":"https://github.com/jaraco/oathtool","tags":["security","otp","totp","hotp","authentication","2fa","cli"],"install":[{"cmd":"pip install oathtool","lang":"bash","label":"Install base library"},{"cmd":"pip install 'oathtool[cli]'","lang":"bash","label":"Install with CLI extras (keyring, clipboard)"}],"dependencies":[{"reason":"Used for secure storage of keys in some CLI operations.","package":"keyring","optional":true},{"reason":"Used for clipboard interaction in some CLI operations.","package":"jaraco.clipboard","optional":true}],"imports":[{"wrong":"from oathtool.totp import TOTP","symbol":"generate_otp","correct":"from oathtool import generate_otp"},{"wrong":"from oathtool.totp import TOTP","symbol":"generate_otp","correct":"import oathtool"}],"quickstart":{"code":"import os\nfrom oathtool.totp import TOTP\n\n# Retrieve your base32-encoded secret key from an environment variable.\n# Example: 'JBSWY3DPEHPK3PXP' (this is a placeholder, use your actual secret)\nsecret_base32 = os.environ.get('OATHTOOL_SECRET', 'JBSWY3DPEHPK3PXP')\n\nif secret_base32 == 'JBSWY3DPEHPK3PXP':\n    print(\"WARNING: Using a placeholder secret. Set OATHTOOL_SECRET environment variable for actual use.\")\n\ntry:\n    # Initialize the TOTP generator with your secret.\n    # oathtool expects the secret to be base32-encoded or raw bytes.\n    # If a base32 string is provided, it will be decoded automatically.\n    totp = TOTP(secret_base32)\n\n    # Generate the current time-based one-time password.\n    current_otp = totp.code()\n    print(f\"Generated TOTP: {current_otp}\")\n\n    # You can also get the remaining time until the next code.\n    # time_left = totp.time_left()\n    # print(f\"Time left until next code: {time_left} seconds\")\n\nexcept Exception as e:\n    print(f\"Error generating OTP: {e}\")\n    print(\"Ensure your OATHTOOL_SECRET is a valid base32 encoded string.\")","lang":"python","description":"This quickstart demonstrates how to generate a TOTP code using a base32-encoded secret key, typically obtained from a 2FA setup process. It emphasizes retrieving the secret securely from an environment variable and includes basic error handling for common key issues."},"warnings":[{"fix":"Ensure your secret key is a valid base32-encoded string (e.g., from a QR code or provided by the service). Tools like `base64.b32decode` can verify format.","message":"Secret keys are typically expected to be base32-encoded strings. While `oathtool` can often handle raw bytes or attempt decoding, providing an invalid base32 string will lead to errors.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always store secret keys securely. Use environment variables (as shown in quickstart), dedicated secret management services, or secure configuration files. For CLI, `oathtool` offers keyring integration.","message":"Hardcoding secret keys directly in your code is a significant security risk. Anyone with access to your code can compromise your accounts.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Implement a robust mechanism to store and increment the HOTP counter reliably. Both client and server must agree on the current counter value. If out of sync, a resynchronization process is usually required.","message":"When using HOTP, the 'counter' value must be meticulously synchronized between the client (your application) and the server. Desynchronization will lead to invalid codes.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"search_vec":"'2.4.0':34 '2fa':54 'albeit':40 'algorithm':29 'authent':53 'base':23,28 'cli':55 'command':6 'command-lin':5 'current':31 'focus':44 'generat':13 'hmac':22 'hmac-bas':21 'hotp':20,52 'infrequ':41 'librari':11 'line':7 'maintain':37 'oathtool':1,2 'one':15 'one-tim':14 'otp':50 'password':17 'python':10 'releas':42 'reliabl':46 'schedul':43 'secur':48,49 'stabl':39 'support':18 'time':16,27 'time-bas':26 'tool':8 'totp':25,51 'version':32","created_at":"2026-04-17T01:21:50.410454+00:00","updated_at":"2026-04-17T01:21:50.410454+00:00","problems":null,"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"2.4.0","cli_name":"oathtool","cli_version":"Traceback (most recent call last):","type":"library","homepage":null,"github":"https://github.com/jaraco/oathtool","docs":null,"changelog":null,"pypi":"https://pypi.org/project/oathtool/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["auth-security","devops"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-30","last_verified":"2026-06-30","next_check":"2026-07-30","install_tag":null}}