{ "info": { "author": "Egor Kolotaev", "author_email": "ekolotaev@gmail.com", "bugtrack_url": null, "classifiers": [ "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Security", "Topic :: Software Development", "Topic :: System :: Networking", "Topic :: System :: Networking :: Firewalls", "Topic :: System :: Systems Administration", "Topic :: Utilities" ], "description": "[![Vakt logo](logo.png)](logo.png)\n\nAttribute-based access control (ABAC) SDK for Python.\n\n[![Build Status](https://travis-ci.org/kolotaev/vakt.svg?branch=master)](https://travis-ci.org/kolotaev/vakt)\n[![codecov.io](https://codecov.io/github/kolotaev/vakt/coverage.svg?branch=master)](https://codecov.io/github/kolotaev/vakt?branch=master)\n[![PyPI version](https://badge.fury.io/py/vakt.svg)](https://badge.fury.io/py/vakt)\n[![Apache 2.0 licensed](https://img.shields.io/badge/License-Apache%202.0-yellow.svg)](https://raw.githubusercontent.com/kolotaev/vakt/master/LICENSE)\n\n------\n\n## Documentation\n\n- [Description](#description)\n- [Concepts](#concepts)\n- [Install](#install)\n- [Usage](#usage)\n- [Components](#components)\n\t- [Policy](#policy)\n\t- [Inquiry](#inquiry)\n\t- [Rules](#rules)\n\t - [Comparison-related](#comparison-related)\n\t - [Logic-related](#logic-related)\n\t - [List-related](#list-related)\n\t - [Network-related](#network-related)\n\t - [String-related](#string-related)\n\t - [Inquiry-related](#inquiry-related)\n\t- [Checker](#checker)\n\t- [Guard](#guard)\n\t- [Storage](#storage)\n - [Memory](#memory)\n - [MongoDB](#mongodb)\n - [Migration](#migration)\n- [JSON](#json)\n- [Logging](#logging)\n- [Examples](./examples)\n- [Acknowledgements](#acknowledgements)\n- [Benchmark](#benchmark)\n- [Development](#development)\n- [License](#license)\n\n\n### Description\n\nVakt is an attribute-based access control ([ABAC](https://en.wikipedia.org/wiki/Attribute-based_access_control))\ntoolkit that is based on policies, also sometimes referred as PBAC.\nABAC stands aside of RBAC and ACL models, giving you\na fine-grained control on definition of the rules that restrict an access to resources and is generally considered a\n\"next generation\" authorization model.\nIn its form Vakt resembles [IAM Policies](https://github.com/awsdocs/iam-user-guide/blob/master/doc_source/access_policies.md), but\nhas a way nicer attribute managing.\n\nSee [concepts](#concepts) section for more details.\n\n*[Back to top](#documentation)*\n\n\n### Concepts\n\nGiven you have some set of resources, you can define a number of policies that will describe access to them\nanswering the following questions:\n\n1. *What resources (resource) are being requested?*\n1. *Who is requesting the resource?*\n1. *What actions (action) are requested to be done on the asked resources?*\n1. *What are the rules that should be satisfied in the context of the request itself?*\n1. *What is resulting effect of the answer on the above questions?*\n\n\nThe overall diagram of `vakt` workflow is:\n\n[![Vakt diagram](diagram.svg)](diagram.svg)\n\n\nVakt allows you to gain:\n\n* Policy Based Access Control _(vakt is based on Policies that describe access rules, strategies to your resources)_\n* Fine-Grained Authorization _(vakt Policies give you fine-grained control over resource's, subject's, action's and context's attributes)_\n* Dynamic Authorization Management _(you can add Policies and change their attributes)_\n* Externalized Authorization Management _(you can build own external AuthZ server with vakt, see examples)_\n\n*[Back to top](#documentation)*\n\n\n### Install\n\nVakt runs on Python >= 3.4. \nPyPy implementation is supported as well.\n\nFor in-memory storage:\n```bash\npip install vakt\n```\n\nFor MongoDB storage:\n```bash\npip install vakt[mongo]\n```\n\n*[Back to top](#documentation)*\n\n\n### Usage\n\nA quick dive-in:\n\n```python\nimport uuid\n\nimport vakt\nfrom vakt.rules import Eq, Any, StartsWith, And, Greater, Less\n\npolicy = vakt.Policy(\n str(uuid.uuid4()),\n actions=[Eq('fork'), Eq('clone')],\n resources=[StartsWith('repos/Google', ci=True)],\n subjects=[{'name': Any(), 'stars': And(Greater(50), Less(999))}],\n effect=vakt.ALLOW_ACCESS,\n context={'referer': 'https://github.com'},\n description=\"\"\"\n Allow to fork or clone any Google repository for\n users that have > 50 and < 999 stars and came from Github\n \"\"\"\n)\nstorage = vakt.MemoryStorage()\nstorage.add(policy)\nguard = vakt.Guard(storage, vakt.RulesChecker())\n\ninq = vakt.Inquiry(action='fork',\n resource='repos/google/tensorflow',\n subject={'name': 'larry', 'stars': 80},\n context={'referer': 'https://github.com'})\n\nassert guard.is_allowed(inq)\n```\n\nFor more examples see [here](./examples).\n\n*[Back to top](#documentation)*\n\n### Components\n\n#### Policy\nPolicy is a main object for defining rules for accessing resources.\nThe main parts reflect questions described in [Concepts](#concepts) section:\n\n* resources - a list of resources. Answers: what is asked?\n* subjects - a list of subjects. Answers: who asks access to resources?\n* actions - a list of actions. Answers: what actions are asked to be performed on resources?\n* context - rules that should be satisfied by the given inquiry's context.\n* effect - If policy matches all the above conditions, what effect does it imply?\nCan be either `vakt.ALLOW_ACCESS` or `vakt.DENY_ACCESS`\n\nAll `resources`, `subjects` and `actions` are described with \na list containing strings, regexes, [Rules](#rules) or dictionaries of strings (attributes) to [Rules](#rules). \nEach element in list acts as logical OR. Each key in a dictionary of Rules acts as logical AND. \n`context` can be described only with a dictionary of [Rules](#rules).\n\nDepending on a way `resources`, `subjects`, `actions` are described, Policy can have either \nString-based or Rule-based type. Can be inspected by `policy.type`. \nThis enforces the use of a concrete Checker implementation. See [Checker](#checker) for more.\n\n```python\nfrom vakt import Policy, ALLOW_ACCESS\nfrom vakt.rules import CIDR, Any, Eq, NotEq, In\n \n# Rule-based policy (defined with Rules and dictionaries of Rules)\nPolicy(\n 1,\n description=\"\"\"\n Allow access to administration interface subcategories: 'panel', 'switch' if user is not \n a developer and came from local IP address.\n \"\"\",\n actions=[Any()],\n resources=[{'category': Eq('administration'), 'sub': In(['panel', 'switch'])}],\n subjects=[{'name': Any(), 'role': NotEq('developer')}],\n effect=ALLOW_ACCESS,\n context={'ip': CIDR('127.0.0.1/32')}\n)\n\n# String-based policy (defined with regular expressions)\nPolicy(\n 2,\n description=\"\"\"\n Allow all readers of the book library whose surnames start with M get and read any book or magazine,\n but only when they connect from local library's computer\n \"\"\",\n effect=ALLOW_ACCESS,\n subjects=['<[\\w]+ M[\\w]+>'],\n resources=('library:books:<.+>', 'office:magazines:<.+>'),\n actions=[''],\n context={'ip': CIDR('192.168.2.0/24')}\n)\n```\n\nBasically you want to create some set of Policies that encompass access rules for your domain and store them for\nmaking future decisions by the [Guard](#guard) component.\n\n```python\nst = MemoryStorage()\nfor p in policies:\n st.add(p)\n```\n\n*[Back to top](#documentation)*\n\n\n#### Inquiry\nInquiry is an object that serves as a mediator between Vakt and outer world request for resource access. All you need\nto do is take any kind of incoming request (REST request, SOAP, etc.) and build an `Inquiry` out of it in order to\nfeed it to Vakt. There are no concrete builders for Inquiry from various request types, since it's a very meticulous\nprocess and you have hands on control for doing it by yourself. Let's see an example:\n\n```python\nfrom vakt import Inquiry\nfrom flask import request, session\n\n...\n\n# if policies are defined on some subject's and resource's attributes with dictionaries of Rules:\ninquiry2 = Inquiry(subject={'login': request.form['username'], 'role': request.form['user_role']},\n action=request.form['action'],\n resource={'book': session.get('book'), 'chapter': request.form['chapter']},\n context={'ip': request.remote_addr})\n \n# if policies are defined with strings or regular expressions:\ninquiry = Inquiry(subject=request.form['username'],\n action=request.form['action'],\n resource=request.form['page'],\n context={'ip': request.remote_addr})\n```\n\nHere we are taking form params from Flask request and additional request information. Then we transform them\nto Inquiry. That's it.\n\nInquiry has several constructor arguments:\n\n* resource - any | dictionary of str -> any. What resource is being asked to be accessed?\n* action - any | dictionary str -> any. What is being asked to be done on the resource?\n* subject - any | dictionary str -> any. Who asks for it?\n* context - dictionary str -> any. What is the context of the request?\n\nIf you were observant enough you might have noticed that Inquiry resembles Policy, where Policy describes multiple\nvariants of resource access from the owner side and Inquiry describes an concrete access scenario from consumer side.\n\n*[Back to top](#documentation)*\n\n\n#### Rules\nRules allow you to describe conditions directly on `action`, `subject`, `resource` and `context` \nor on their attributes.\nIf at least one Rule in the Rule-set is not satisfied Inquiry is rejected by given Policy.\n\nAttaching a Rule-set to a Policy is simple. Here are some examples:\n\n```python\nfrom vakt import Policy, rules\n\nPolicy(\n ...,\n subjects=[{'name': rules.Eq('.KIMZihH0gsrc')}],\n),\n\nPolicy(\n ...,\n actions=[rules.Eq('get'), rules.Eq('list'), rules.Eq('read')],\n),\n\nPolicy(\n ...,\n context={\n 'secret': rules.string.Equal('.KIMZihH0gsrc'),\n 'ip': rules.net.CIDR('192.168.0.15/24')\n },\n)\n```\n\nThere are a number of different Rule types, see below.\n\nIf the existing Rules are not enough for you, feel free to define your [own](./examples/extending.py).\n\n##### Comparison-related\n\n| Rule | Example in Policy | Example in Inquiry | Notes |\n| ------------- |-------------|-------------|-------------|\n| Eq | `'age': Eq(40)` | `'age': 40`| |\n| NotEq | `'age': NotEq(40)` | `'age': 40`| |\n| Greater | `'height': Greater(6,2)` | `'height': 5.8`| |\n| Less | `'height': Less(6,2)` | `'height': 5.8`| |\n| GreaterOrEqual | `'stars': GreaterOrEqual(300)` | `'stars': 77`| |\n| LessOrEqual | `'stars': LessOrEqual(300)` | `'stars': 300`| |\n\n##### Logic-related\n\n| Rule | Example in Policy | Example in Inquiry | Notes |\n| ------------- |-------------|-------------|-------------|\n| Truthy | `'admin': Truthy()` | `'admin': user.is_admin()`| Evaluates on Inquiry creation |\n| Falsy | `'admin': Falsy()` | `'admin': lambda x: x.is_admin()`| Evaluates on Inquiry creation |\n| Not | `'age': Not(Greater(90))` | `'age': 40` | |\n| And | `'stars': And(Greater(50), Less(89))` | `'stars': 78` | Also, attributes in dictionary of Rules act as AND logic |\n| Or | `'stars': Or(Greater(50), Less(120), Eq(8888))` | `'stars': 78` | Also, rules in a list of, say, `actions` act as OR logic |\n| Any | `actions=[Any()]` | `action='get'`, `action='foo'` | Placeholder that fits any value |\n| Neither | `subjects=[Neither()]` | `subject='Max'`, `subject='Joe'` | Not very useful, left only as a counterpart of Any |\n\n##### List-related\n| Rule | Example in Policy | Example in Inquiry | Notes |\n| ------------- |-------------|-------------|-------------|\n| In | `'method': In('get', 'post')` | `'method': 'get'`| |\n| NotIn | `'method': NotIn('get', 'post')` | `'method': 'get'`| |\n| AllIn | `'name': AllIn('Max', 'Joe')` | `'name': ['Max', 'Joe']`| |\n| AllNotIn | `'name': AllNotIn('Max', 'Joe')` | `'name': ['Max', 'Joe']`| |\n| AnyIn | `'height': AnyIn(5.9, 7.5, 4.9)` | `'height': [7.55]`| |\n| AnyNotIn | `'height': AnyNotIn(5.9, 7.5, 4.9)` | `'height': [7.55]`| |\n\n##### Network-related\n\n| Rule | Example in Policy | Example in Inquiry | Notes |\n| ------------- |-------------|-------------|-------------|\n| CIDR | `'ip': CIDR('192.168.2.0/24')` | `'ip': 192.168.2.4`| |\n\n##### String-related\n| Rule | Example in Policy | Example in Inquiry | Notes |\n| ------------- |-------------|-------------|-------------|\n| Equal | `'name': Equal('max', ci=True)` | `'name': 'Max'`| Aliased as `StrEqual`. Use instead of `Eq` it you want string-type check and case-insensitivity |\n| PairsEqual | `'names': PairsEqual()` | `'names': ['Bob', 'Bob']`| Aliased as `StrPairsEqual` |\n| RegexMatch | `'file': RegexMatch(r'\\.rb$')` | `'file': 'test.rb'`| |\n| StartsWith | `'file': StartsWith('logs-')` | `'file': 'logs-data-101967.log'`| Supports case-insensitivity |\n| EndsWith | `'file': EndsWith('.log')` | `'file': 'logs-data-101967.log'`| Supports case-insensitivity |\n| Contains | `'file': Contains('sun')` | `'file': 'observations-sunny-days.csv'`| Supports case-insensitivity |\n\n##### Inquiry-related\n\nInquiry-related rules are not usable since v1.2, so you very likely won't need them.\nPartially they served as attributes workaround for inquiry elements when placed in `context`.\n\n| Rule | Example in Policy | Example in Inquiry | Notes |\n| ------------- |-------------|-------------|-------------|\n| SubjectEqual | `'data': SubjectEqual()` | `Inquiry(subject='Max')`| Works only for strings |\n| ActionEqual | `'data': ActionEqual()` | `Inquiry(action='get')`| Works only for strings |\n| ResourceIn | `'data': ResourceIn()` | `Inquiry(resource='/books/')`| Works only for strings |\n\n\n*[Back to top](#documentation)*\n\n\n#### Checker\nChecker allows you to check whether Policy matches Inquiry by concrete field (`subject`, `action`, etc.). It's used\ninternally by [Guard](#guard), but you should be aware of Checker types:\n\n* RulesChecker - universal type that is used to check match of Policies defined with Rules or dictionaries of Rules\n(Rule-based Policy type). It gives you the highest flexibility.\nMost of the time you will use this type of Polices and thus this type of a Checker.\nBesides, it's much more performant than RegexChecker. See [benchmark](#benchmark) for more details.\n\n```python\nfrom vakt import RulesChecker\n\nch = RulesChecker()\n# etc.\n```\n\n* RegexChecker - checks match by regex test for policies defined with strings and regexps (String-based Policy type).\nThis means that all you Policies\ncan be defined in regex syntax (but if no regex defined in Policy falls back to simple string equality test) - it\ngives you better flexibility compared to simple strings, but carries a burden of relatively slow performance.\nYou can configure a LRU cache size to adjust performance to your needs:\n\n```python\nfrom vakt import RegexChecker\n\nch = RegexChecker(2048)\nch2 = RegexChecker(512)\n# etc.\n```\nSee [benchmark](#benchmark) for more details.\n\nSyntax for description of Policy fields is:\n```\n ''\n 'foo<[abc]{2}>bar'\n 'foo<\\w+>'\n 'foo'\n```\nWhere `<>` are delimiters of a regular expression boundaries part. Custom Policy can redefine them by overriding\n`start_tag` and `end_tag` properties. Generally you always want to use the first variant: ``.\n\n* StringExactChecker - the most quick checker:\n```\nChecker that uses exact string equality. Case-sensitive.\nE.g. 'sun' in 'sunny' - False\n 'sun' in 'sun' - True\n```\n* StringFuzzyChecker - quick checker with some extent of flexibility:\n```\nChecker that uses fuzzy substring equality. Case-sensitive.\nE.g. 'sun' in 'sunny' - True\n 'sun' in 'sun' - True\n```\n\nNote, that some [Storage](#storage) handlers can already check if Policy fits Inquiry in\n`find_for_inquiry()` method by performing specific to that storage queries - Storage can (and generally should)\ndecide on the type of actions based on the checker class passed to [Guard](#guard) constructor\n(or to `find_for_inquiry()` directly).\n\nRegardless of the results returned by a Storage the Checker is always the last row of control\nbefore Vakt makes a decision.\n\n*[Back to top](#documentation)*\n\n\n#### Guard\nGuard component is a main entry point for Vakt to make a decision. It has one method `is_allowed` that passed an\n[Inquiry](#inquiry) gives you a boolean answer: is that Inquiry allowed or not?\n\nGuard is constructed with [Storage](#storage) and [Checker](#checker).\n\n__Policies that have String-based type won't match if RulesChecker is used and vise-versa.__\n\n```python\nst = MemoryStorage()\n# And persist all our Policies so that to start serving our library.\nfor p in policies:\n st.add(p)\n\nguard = Guard(st, RulesChecker())\n\nif guard.is_allowed(inquiry):\n return \"You've been logged-in\", 200\nelse:\n return \"Go away, you violator!\", 401\n```\n\n*[Back to top](#documentation)*\n\n\n#### Storage\nStorage is a component that gives an interface for manipulating [Policies](#policy) persistence in various places.\n\nIt provides the following methods:\n```python\nadd(policy) # Store a Policy\nget(uid) # Retrieve a Policy by its ID\nget_all(limit, offset) # Retrieve all stored Policies (with pagination)\nupdate(policy) # Store an updated Policy\ndelete(uid) # Delete Policy from storage by its ID\nfind_for_inquiry(inquiry) # Retrieve Policies that match the given Inquiry\n```\n\nStorage may have various backend implementations (RDBMS, NoSQL databases, etc.). Vakt ships some Storage implementations\nout of the box. See below.\n\n##### Memory\nImplementation that stores Policies in memory. It's not backed by any file or something, so every restart of your\napplication will swipe out everything that was stored. Useful for testing.\n\n##### MongoDB\nMongoDB is chosen as the most popular and widespread NO-SQL database.\n\n\n```python\nfrom pymongo import MongoClient\nfrom vakt.storage.mongo import MongoStorage\n\nclient = MongoClient('localhost', 27017)\nstorage = MongoStorage(client, 'database-name', collection='optional-collection-name')\n```\n\nDefault collection name is 'vakt_policies'.\n\nActions are the same as for any Storage that conforms interface of `vakt.storage.abc.Storage` base class.\n\nBeware that currently MongoStorage supports indexed `find_for_inquiry()` only for StringExact and StringFuzzy checkers.\nRegexChecker (see [this issue](https://jira.mongodb.org/browse/SERVER-11947)) and RulesChecker simply\nreturn all the Policies from the database.\n\n*[Back to top](#documentation)*\n\n\n#### Migration\n\n`vakt.migration` is a set of components that are useful from the perspective of the [Storage](#storage).\nIt's recommended to favor it over manual actions on DB schema/data\nsince it's aware of Vakt requirements to Policies data. But it's not mandatory, anyway.\nHowever it's up to a particular Storage to decide whether it needs migrations or not.\nIt consists of 3 components:\n* `Migration`\n* `MigrationSet`\n* `Migrator`\n\n`Migration` allows you to describe data modifications between versions.\nEach storage can have a number of `Migration` classes to address different releases with the order of the migration\nspecified in `order` property.\nShould be located inside particular storage module and implement `vakt.storage.migration.Migration`.\nMigration has 2 main methods (as you might guess) and 1 property:\n- `up` - runs db \"schema\" upwards\n- `down` - runs db \"schema\" downwards (rolls back the actions of `up`)\n- `order` - tells the number of the current migration in a row\n\n`MigrationSet` is a component that represents a collection of Migrations for a Storage.\nYou should define your own migration-set. It should be located inside particular storage module and implement\n`vakt.storage.migration.MigrationSet`. It has 3 methods that lest unimplemented:\n- `migrations` - should return all initialized Migration objects\n- `save_applied_number` - saves a number of a lst applied up migration in the Storage for later reference\n- `last_applied` - returns a number of a lst applied up migration from the Storage\n\n`Migrator` is an executor of a migrations. It can execute all migrations up or down, or execute a particular migration\nif `number` argument is provided.\n\nExample usage:\n\n```python\nfrom pymongo import MongoClient\nfrom vakt.storage.mongo import MongoStorage, MongoMigrationSet\nfrom vakt.storage.migration import Migrator\n\nclient = MongoClient('localhost', 27017)\nstorage = MongoStorage(client, 'database-name', collection='optional-collection-name')\n\nmigrator = Migrator(MongoMigrationSet(storage))\nmigrator.up()\n...\nmigrator.down()\n...\nmigrator.up(number=2)\n...\nmigrator.down(number=2)\n```\n\n*[Back to top](#documentation)*\n\n\n### JSON\n\nAll Policies, Inquiries and Rules can be JSON-serialized and deserialized.\n\nFor example, for a Policy all you need is just run:\n```python\nfrom vakt.policy import Policy\n\npolicy = Policy('1')\n\njson_policy = policy.to_json()\nprint(json_policy)\n# {\"actions\": [], \"description\": null, \"effect\": \"deny\", \"uid\": \"1\",\n# \"resources\": [], \"context\": {}, \"subjects\": []}\n\npolicy = Policy.from_json(json_policy)\nprint(policy)\n# \n```\n\nThe same goes for Rules, Inquiries.\nAll custom classes derived from them support this functionality as well.\nIf you do not derive from Vakt's classes, but want this option, you can mix-in `vakt.util.JsonSerializer` class.\n\n```python\nfrom vakt.util import JsonSerializer\n\nclass CustomInquiry(JsonSerializer):\n pass\n```\n\n*[Back to top](#documentation)*\n\n\n### Logging\n\nVakt follows a common logging pattern for libraries:\n\nIts corresponding modules log all the events that happen but the log messages by default are handled by `NullHandler`.\nIt's up to the outer code/application to provide desired log handlers, filters, levels, etc.\n\nFor example:\n\n```python\nimport logging\n\nroot = logging.getLogger()\nroot.setLevel(logging.INFO)\nroot.addHandler(logging.StreamHandler())\n\n... # here go all the Vakt calls.\n```\n\nVakt logs can be comprehended in 2 basic levels:\n1. *Error/Exception* - informs about exceptions and errors during Vakt work.\n2. *Info* - informs about incoming inquires and their resolution.\n\n*[Back to top](#documentation)*\n\n\n### Acknowledgements\n\nInitial code ideas of Vakt are based on\n[Amazon IAM Policies](https://github.com/awsdocs/iam-user-guide/blob/master/doc_source/access_policies.md) and\n[Ladon](https://github.com/ory/ladon) Policies SDK as its reference implementation.\n\n*[Back to top](#documentation)*\n\n\n### Benchmark\n\nYou can see how much time it takes for a single Inquiry to be processed given we have a number of unique Policies in a\nStorage. \nFor [MemoryStorage](#memory) it measures the runtime of a decision-making process for all \nthe existing Policies when [Guard's](#guard) code iterates the whole list of Policies to decide if \nInquiry is allowed or not. In case of other Storages the mileage\nmay vary since they may return a smaller subset of Policies that fit the given Inquiry. \nDon't forget that most external Storages add some time penalty to perform I/O operations.\nThe runtime also depends on a Policy-type used (and thus checker): RulesChecker performs much better than RegexChecker.\n\nExample:\n\n```bash\npython3 benchmark.py --checker regex --storage memory -n 1000\n```\n\nOutput is:\n> Populating MemoryStorage with Policies
\n> ......................
\n> START BENCHMARK!
\n> Number of unique Policies in DB: 1,000
\n> Among them Policies with the same regexp pattern: 0
\n> Checker used: RegexChecker
\n> Decision for 1 Inquiry took: 0.4451 seconds
\n> Inquiry passed the guard? False
\n\nScript usage:\n```\nusage: benchmark.py [-h] [-n [POLICIES_NUMBER]] [-d {mongo,memory}]\n [-c {regex,rules,exact,fuzzy}] [--regexp] [--same SAME]\n [--cache CACHE]\n\nRun vakt benchmark.\n\noptional arguments:\n -h, --help show this help message and exit\n -n [POLICIES_NUMBER], --number [POLICIES_NUMBER]\n number of policies to create in DB (default: 100000)\n -d {mongo,memory}, --storage {mongo,memory}\n type of storage (default: memory)\n -c {regex,rules,exact,fuzzy}, --checker {regex,rules,exact,fuzzy}\n type of checker (default: regex)\n\nregex policy related:\n --regexp should Policies be defined without Regex syntax?\n (default: True)\n --same SAME number of similar regexps in Policy\n --cache CACHE number of LRU-cache for RegexChecker (default:\n RegexChecker's default cache-size)\n```\n\n*[Back to top](#documentation)*\n\n\n### Development\n\nTo hack Vakt locally run:\n\n```bash\n$ ... # activate virtual environment w/ preferred method (optional)\n$ pip install -e .[dev,mongo] # to install all dependencies\n$ pytest -m \"not integration\" # to run non-integration tests with coverage report\n$ pytest --cov=vakt tests/ # to get coverage report\n$ pylint vakt # to check code quality with PyLint\n```\n\nTo run only integration tests (for Storage adapters other than `MemoryStorage`):\n\n```bash\n$ docker run --rm -d -p 27017:27017 mongo\n$ pytest -m integration\n```\n\nOptionally you can use `make` to perform development tasks.\n\n*[Back to top](#documentation)*\n\n\n### License\n\nThe source code is licensed under Apache License Version 2.0\n\n*[Back to top](#documentation)*\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/kolotaev/vakt", "keywords": "ACL ABAC access-control policy security authorization permission", "license": "Apache 2.0 license", "maintainer": "", "maintainer_email": "", "name": "vakt", "package_url": "https://pypi.org/project/vakt/", "platform": "", "project_url": "https://pypi.org/project/vakt/", "project_urls": { "Homepage": "http://github.com/kolotaev/vakt" }, "release_url": "https://pypi.org/project/vakt/1.2.1/", "requires_dist": null, "requires_python": "", "summary": "Attribute-based access control (ABAC) SDK for Python", "version": "1.2.1" }, "last_serial": 5181977, "releases": { "1.0.2": [ { "comment_text": "", "digests": { "md5": "0182f7582c65acdd916f83fa46abbee3", "sha256": "55f137989495f877cbe2a1b115fa5d1f0aa3651eacec0b25fdebcf06ada5a05f" }, "downloads": -1, "filename": "vakt-1.0.2.tar.gz", "has_sig": false, "md5_digest": "0182f7582c65acdd916f83fa46abbee3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7278, "upload_time": "2018-06-05T16:37:03", "url": "https://files.pythonhosted.org/packages/93/0b/e3ad5ea4ba142025786c688ba4f009db7149124658b9fa62cc9560b991ec/vakt-1.0.2.tar.gz" } ], "1.0.3": [ { "comment_text": "", "digests": { "md5": "bd58e3d6265c33cd4cd4c08562eac06e", "sha256": "802f180e207ced57d745e2e06ae9907f3c7adb1b77afef09ff546f8f0784a0ff" }, "downloads": -1, "filename": "vakt-1.0.3.tar.gz", "has_sig": false, "md5_digest": "bd58e3d6265c33cd4cd4c08562eac06e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17999, "upload_time": "2018-08-30T09:18:03", "url": "https://files.pythonhosted.org/packages/72/33/9f713ff5722cae78e196202037c622ee34395720376716f33dd04ba12a58/vakt-1.0.3.tar.gz" } ], "1.0.4": [ { "comment_text": "", "digests": { "md5": "ae63e37c9b2247243753a6f76786b4b3", "sha256": "fc72d0ab5e07b40cfbb220f3c2ce8ef37e0f1c005a630ad18332e1882350559d" }, "downloads": -1, "filename": "vakt-1.0.4.tar.gz", "has_sig": false, "md5_digest": "ae63e37c9b2247243753a6f76786b4b3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18052, "upload_time": "2018-08-30T09:45:49", "url": "https://files.pythonhosted.org/packages/5b/84/0c3ea2c3c9d734aa9cfbc32d6994d96b6c37603fabfbcf1d4afd46949813/vakt-1.0.4.tar.gz" } ], "1.0.5": [ { "comment_text": "", "digests": { "md5": "ecffe3238160854cc54508fed3417882", "sha256": "389683d2fcc50351219eae747f1d7448e25528dec6fea30d7692170a0fd65c59" }, "downloads": -1, "filename": "vakt-1.0.5.tar.gz", "has_sig": false, "md5_digest": "ecffe3238160854cc54508fed3417882", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18055, "upload_time": "2018-08-30T09:54:13", "url": "https://files.pythonhosted.org/packages/6f/a5/e18c956617f3ab47d5c690d19e45a65729922e1abb6938798c9dd4123bd3/vakt-1.0.5.tar.gz" } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "a72e87d943b9f6f4b7c33c7c244c8b5c", "sha256": "c5521e163f2523467e8e28c94514b10fc9a897cd577217e8355af93c6b9525ec" }, "downloads": -1, "filename": "vakt-1.1.0.tar.gz", "has_sig": false, "md5_digest": "a72e87d943b9f6f4b7c33c7c244c8b5c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21776, "upload_time": "2018-09-03T15:24:44", "url": "https://files.pythonhosted.org/packages/b6/80/f32f0abd5dbe03c4bbe22d657f1831b92a498e7aaed5c2d01fb3f1fde020/vakt-1.1.0.tar.gz" } ], "1.1.1": [ { "comment_text": "", "digests": { "md5": "cea3b04047f904873d342ca6fab84bd7", "sha256": "dc1ee93b899f7dbb5d680ecb1773eff0bcf329bba4381383686dc20c04ff8703" }, "downloads": -1, "filename": "vakt-1.1.1.tar.gz", "has_sig": false, "md5_digest": "cea3b04047f904873d342ca6fab84bd7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22514, "upload_time": "2019-01-22T14:14:20", "url": "https://files.pythonhosted.org/packages/8e/38/bb79b65bcedc2eda6c4fe43abda4f16cf1ce9d4bcec66065897d88e9f81b/vakt-1.1.1.tar.gz" } ], "1.2.0": [ { "comment_text": "", "digests": { "md5": "bb82637b9758a3d312f84567c9498613", "sha256": "b2a7eff14ded1c9b9a24af33e5bc0cecba0d46e8ba9fa302ca8b60841c8e7f13" }, "downloads": -1, "filename": "vakt-1.2.0.tar.gz", "has_sig": false, "md5_digest": "bb82637b9758a3d312f84567c9498613", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 42010, "upload_time": "2019-04-24T11:32:54", "url": "https://files.pythonhosted.org/packages/17/59/2549c523c777d7b2a23e31cc32eaf8029f4acb4d667389be1c839b4ae4e0/vakt-1.2.0.tar.gz" } ], "1.2.1": [ { "comment_text": "", "digests": { "md5": "105729af91d7ca44951478a3849e6445", "sha256": "235ab3260fa6a13c8454e940766ff26bc253b11fdd33a50edc45e851424521ce" }, "downloads": -1, "filename": "vakt-1.2.1.tar.gz", "has_sig": false, "md5_digest": "105729af91d7ca44951478a3849e6445", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 39539, "upload_time": "2019-04-24T12:12:15", "url": "https://files.pythonhosted.org/packages/08/ad/8965c45f1fe7f91d37cc527949d2f00ff109bc0ebb0ea1224d67da1456a7/vakt-1.2.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "105729af91d7ca44951478a3849e6445", "sha256": "235ab3260fa6a13c8454e940766ff26bc253b11fdd33a50edc45e851424521ce" }, "downloads": -1, "filename": "vakt-1.2.1.tar.gz", "has_sig": false, "md5_digest": "105729af91d7ca44951478a3849e6445", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 39539, "upload_time": "2019-04-24T12:12:15", "url": "https://files.pythonhosted.org/packages/08/ad/8965c45f1fe7f91d37cc527949d2f00ff109bc0ebb0ea1224d67da1456a7/vakt-1.2.1.tar.gz" } ] }