{ "info": { "author": "Greger Wedel", "author_email": "greger@greger.io", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3" ], "description": "# README and Getting Started\n\nThis Python library is a wrapper around pyjwt to support JWT creation and validation as well\nas payload handling (scopes, auth level, etc).\n\n## Use case\n\nThe typical use is a micro services architecture where a single auth service is responsible for issuing JWT tokens for clients you may or may not trust. \nIn order to scale without a central point of failure, the JWT token should contain all necessary information for each micro service\nto trust the identity of the requestor, as well what the requestor can access. This is done through embedding meta information in the\nJWT token and signing it with a private key only known to the authn/authz service.\n\nWith only knowledge of the public key, any service can verify the signature of the JWT and thus prove it's authenticity.\n\n**NOTE!!!** Do not store secrets in the payload, it is not encrypted and can easily be decoded and read.\n\n## Typical use\n\nMake your own wrapper through sub-classing the APIJwt class. In the initialisation, load the private key (for the\nauthn/authz service) and public key(s) for the all other services. In the authn/authz service that encodes JWTs, set all the extra payload keys that should be \nallowed (i.e. info you want to convey to the other services receiving the JWT), and then set the allowed values for each\nof the keys. The decode does not validate the payload, just the signature, so these configurations are thus not\nneeded.\n\nYou can now use the encode() and decode() functions inherited from APIJwt to encode (and sign) the JWT, as well as\ndecode.\n\n## Example use\n\nExample wrapper where you add set your own configuration parameters\n\n from api_jwt import APIJwt\n \n class HudyaJWT(APIJwt):\n \n def __init__(self, *args, **kwargs):\n if settings.JWT_KEY_PRIVATE: # This could be loaded from os.env(), it should be base64 encoded\n # It should be in pem format and not be encrypted\n privkey = base64.b64decode(settings.JWT_KEY_PRIVATE).decode('utf-8')\n else:\n privkey = None\n if settings.JWT_KEY_PUBLIC: # This could be loaded from os.env(), it should be base64 encoded in pem format\n pubkey = base64.b64decode(settings.JWT_KEY_PUBLIC).decode('utf-8')\n else:\n pubkey = None\n super().__init__(\n public_keys=pubkey,\n private_key=privkey,\n ttl=int(settings.JWT_TOKEN_TTL), # This is in seconds\n *args, **kwargs)\n \n # The below is only required for encoding\n self.set_allowed('level', [\n 0.0, # Level 0, no authentication\n 1.0, # External auth\n 2.0, # Password/single-factor\n 3.0, # Multi-factor\n 3.1, # Yubikey\n 3.5, # External multi-factor\n 4.0 # Certificate-level\n ])\n self.set_allowed('keys', {\n 'user': 'auth_user',\n 'support': 'auth_support',\n 'admin': 'auth_admin'\n })\n self.set_allowed('scopes', {\n 'PER_KEY': { # Use single key with 'PER_KEY' to set allowed values based on key\n 'user': ['user:all', 'NO', 'SE', 'DK'],\n 'support': [\n 'support:all',\n 'support:insurance',\n 'support:power',\n 'support:mobile'\n ],\n 'admin': ['admin:all', 'user:all']\n }\n })\n\nWith this class, you can encode a JWT:\n\n jwt_obj = HudyaJWT()\n token = jwt_obj.encode(\n subject='user@domain.com',\n level='3.1',\n factor='yubikey',\n target='user@domain.com', # Used if the target of the scopes is different from subject\n key='support,\n exp=3600,\n scopes=['support:mobile'],\n dnt=0, # Normal user, full tracking\n )\n if token is None:\n raise\n \nDecoding is super-simple:\n\n jwt_data = HudyaJWT()\n payload = jwt_data.decode(token)\n if not jwt_data.is_valid:\n raise ValidationError(\"JWT is not valid\")\n if 'support:mobile' in payload['scope']:\n print(\"Access granted!\")\n\n## How to release\n\nRunning `docker-compose up -d` without env var COMMAND set will start up the container and run run.sh, which\nwill result in the tests being run and the container be kept running for subsequent docker exec commands.\n\nTo do a test build and release, run docker-compose with `COMMAND=\"build\"` as an env variable (which will be passed into run.sh as a parameter).\nIn this case, the .pypirc file in the root dir of the docker build will be copied in. A pypitest server entry is expected.\n\nTo release, make sure you have the pypi server entry in .pypirc for release and run with COMMAND set to \"release\", e.g.:\n\n`export COMMAND=\"release\";docker-compose up -d`\n\n\n**NOTE!!** Due to the volume set up in docker-compose.yml, the sources will be in sync inside and outside of the container, so\nthere is no need to rebuild the container.\n\n**Do not forget to change CHANGELOG.md.**", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/gregertw/api_jwt", "keywords": "", "license": "Apache2", "maintainer": "", "maintainer_email": "", "name": "api-jwt", "package_url": "https://pypi.org/project/api-jwt/", "platform": "", "project_url": "https://pypi.org/project/api-jwt/", "project_urls": { "Homepage": "https://github.com/gregertw/api_jwt" }, "release_url": "https://pypi.org/project/api-jwt/1.2.0/", "requires_dist": null, "requires_python": "", "summary": "Library for JWT encoding/decoding specifically adapted to use in APIs", "version": "1.2.0" }, "last_serial": 4857503, "releases": { "1.2.0": [ { "comment_text": "", "digests": { "md5": "0410b9c75484b6a8722f098bf6af5c0b", "sha256": "474e0bef717783c7ebf0ea0b07114818903d933075205b31d431b947393f7540" }, "downloads": -1, "filename": "api_jwt-1.2.0.tar.gz", "has_sig": false, "md5_digest": "0410b9c75484b6a8722f098bf6af5c0b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14694, "upload_time": "2019-02-23T07:19:28", "url": "https://files.pythonhosted.org/packages/03/be/df8e6f9c0c54800151971af0be0c60f31641c765f54fc2eb67594763138a/api_jwt-1.2.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "0410b9c75484b6a8722f098bf6af5c0b", "sha256": "474e0bef717783c7ebf0ea0b07114818903d933075205b31d431b947393f7540" }, "downloads": -1, "filename": "api_jwt-1.2.0.tar.gz", "has_sig": false, "md5_digest": "0410b9c75484b6a8722f098bf6af5c0b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14694, "upload_time": "2019-02-23T07:19:28", "url": "https://files.pythonhosted.org/packages/03/be/df8e6f9c0c54800151971af0be0c60f31641c765f54fc2eb67594763138a/api_jwt-1.2.0.tar.gz" } ] }