diff --git a/Makefile b/Makefile
index 66ee76137e23e4db9520609f80001323662c7f5d..c66baebc180e676cb96316fcf8ba5200501cbc4f 100644
--- a/Makefile
+++ b/Makefile
@@ -41,13 +41,16 @@ clean-proto:
 	find . -name '*_pb2.py' -exec rm -f {} +
 	find . -name '*_pb2_grpc.py' -exec rm -f {} +
 
-install-requirements:
+install-build-requirements:
 	pip install -r build-requirements.txt
 
-lint: install-requirements
+install-requirements:
+	pip install -r requirements.txt
+
+lint: install-build-requirements
 	flake8 perxis/
 
-generate: clean-proto install-requirements
+generate: clean-proto install-build-requirements
 	cp -avR $(SRC_PROTO_FILES_DIR) $(COPIES_PROTO_FILES_DIR)
 	mv $(COPIES_PROTO_FILES_DIR)/collections $(COPIES_PROTO_FILES_DIR)/collections_perxis
 	find $(COPIES_PROTO_FILES_DIR) -name '*.proto' -exec python3 -m grpc_tools.protoc -I${COPIES_PROTO_FILES_DIR} --python_out=$(OUTPUT_FILES_DIR) --grpc_python_out=$(OUTPUT_FILES_DIR) {} +
@@ -63,5 +66,5 @@ release: clean generate
 	devpi login root --password $(PYPI_PASSWORD)
 	devpi upload --no-vcs
 
-install: clean generate
+install: clean generate install-requirements
 	python setup.py install
diff --git a/build-requirements.txt b/build-requirements.txt
index 549bd3857da6c53030cf2a1876dfc7552c6aed88..55e9caad4ec8e55e901d9b63dd0f99b80f31c2f5 100644
--- a/build-requirements.txt
+++ b/build-requirements.txt
@@ -8,8 +8,8 @@ devpi-common==3.6.0
 distlib==0.3.1
 filelock==3.0.12
 flake8==3.9.0
-grpcio==1.36.1
-grpcio-tools==1.36.1
+grpcio==1.37.0
+grpcio-tools==1.37.0
 idna==2.10
 importlib-metadata==3.10.0
 lazy==1.4
diff --git a/examples/collections_auth_client.py b/examples/collections_auth_client.py
new file mode 100644
index 0000000000000000000000000000000000000000..16cdd2f4a0925be67e83e8457a3f244781368aa1
--- /dev/null
+++ b/examples/collections_auth_client.py
@@ -0,0 +1,37 @@
+import logging
+
+import grpc
+from oauthlib.oauth2 import BackendApplicationClient
+
+from perxis.auth import OAuth2Plugin
+from perxis.collections_perxis.collections_pb2 import ListRequest
+from perxis.collections_perxis.collections_pb2_grpc import CollectionsStub
+
+
+def main():
+    client_id = 'YGPQSAUPgco4iTQxNejtXDjFVwPmYT3n'
+    client_secret = '_d6F-VlQGmcsU25AXIoCU4EU3v56-28P6jwUHkutg_hSPseConphyLs3F-Buuq1h'
+    token_url = 'https://adwz.auth0.com/oauth/token'
+    audience = 'some'
+
+    oauth2_plugin = OAuth2Plugin(
+        client=BackendApplicationClient(client_id=client_id),
+        client_secret=client_secret,
+        token_url=token_url,
+        audience=audience
+    )
+
+    call_credentials = grpc.metadata_call_credentials(oauth2_plugin, name='auth')
+    channel_credentials = grpc.ssl_channel_credentials()
+    composite_credentials = grpc.composite_channel_credentials(
+            channel_credentials, call_credentials
+    )
+    with grpc.secure_channel('envoy.perxis.pt.perx.ru:443', composite_credentials) as channel:
+        stub = CollectionsStub(channel)
+        collections = stub.List(ListRequest(space_id="c1mrvup3e6litup7tf0g", env_id="master"))
+        print(collections)
+
+
+if __name__ == '__main__':
+    logging.basicConfig(level=logging.INFO)
+    main()
diff --git a/examples/collections_client.py b/examples/collections_client.py
index b2f50673a3981604f4b718c337f3e3bbbcfbfe77..b2383d9b8606ef8de26273320a7262c2da76e3fa 100644
--- a/examples/collections_client.py
+++ b/examples/collections_client.py
@@ -1,22 +1,83 @@
 
-import asyncio
 import logging
 
 import grpc
 
-from perxis.collections_perxis.collections_pb2 import GetRequest
-from perxis.collections_perxis.collections_pb2_grpc import CollectionsStub
+from perxis.collections_perxis import collections_pb2, collections_pb2_grpc
 
 
-async def main() -> None:
-    async with grpc.aio.insecure_channel('localhost:50051') as channel:
-        stub = CollectionsStub(channel)
-        collections = await stub.List()
-        print('List collections', collections)
-        collection = await stub.Get(GetRequest(space_id='1', env_id='1', collection_id='1'))
-        print('Retrieve collection', collection)
+ACCESS_TOKEN = 'Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik5UWXhSVE5FTnprek5qSkVPRFkyTmpORk9VVXhRVEUzUmpWRVFqY3pRVE5CTjBJeE1ETTNOUSJ9.eyJodHRwczovL2hvb3AucGVyeC5ydS9pZGVudGl0eSI6eyJncm91cHMiOltdfSwibmlja25hbWUiOiJnb3NoaWstZSIsIm5hbWUiOiJHZW9yZ2l5IEV0ZXJldnNraXkiLCJwaWN0dXJlIjoiaHR0cHM6Ly9hdmF0YXJzLmdpdGh1YnVzZXJjb250ZW50LmNvbS91Lzc2NjAzMzE_dj00IiwidXBkYXRlZF9hdCI6IjIwMjEtMDQtMjBUMDc6MDM6NTAuMzM5WiIsImlzcyI6Imh0dHBzOi8vYWR3ei5hdXRoMC5jb20vIiwic3ViIjoiZ2l0aHVifDc2NjAzMzEiLCJhdWQiOiJ6d3JaaGZrd0owNlQ3MlE4ZXhOZHRFS0NxTzBja0ZpWCIsImlhdCI6MTYxODkwMjIzMCwiZXhwIjoxNjE4OTM4MjMwLCJhdXRoX3RpbWUiOjE2MTg5MDIyMzAsImF0X2hhc2giOiJNZU1FdkxBRm14N1JXZ3pDaEwxdlBBIiwibm9uY2UiOiJrTEExZDZhM0V4cjBDMlU5UVBoNG5DUkhiQ3ZvcU1TdiJ9.BqkhCwRi7_LZ0FANXU9fe_9MP0lIq7TewBo3OiSe92FXSXmyKMIEeUPnPtp0oUzf6taFgVCyQJiKrbJfpnlZYK4rVetPEWKvGpMiyv4IsQ_6Y7ZTBKdOFZrej0sKB9EFUjkBX01g4ihDyLUaz3xJYZX4qLApEPS4ubAFTuqsa_M1-rI9_8cXa3leMnQHqEOkL2Cb-N2M2uWrXYYzch8PpVyTMiBK39CA8-EJ1z8MGwjcKsqR8wryG4OWCAn84i8kt7wFAad9Tjb6YsCp1v8HlZR4cUj7u2-ztEzHDs5BNbG2dyloizBqh1XScCA261asybQgYDJDEBmqztk9mKgsVg'
+SPACE_ID = "c1mrvup3e6litup7tf0g"
+ENV_ID = "master"
+
+
+def create(stub, space_id, env_id, coll_id, name):
+    return stub.Create.with_call(
+        collections_pb2.CreateRequest(coll=collections_pb2.Collection(space_id=space_id, env_id=env_id, id=coll_id, name=name)),
+        metadata=(
+            ('authorization', f'{ACCESS_TOKEN}'),
+        )
+    )
+
+
+def get(stub, space_id, env_id, coll_id):
+    return stub.Get.with_call(
+        collections_pb2.GetRequest(space_id=space_id, env_id=env_id, collection_id=coll_id),
+        metadata=(
+            ('authorization', f'{ACCESS_TOKEN}'),
+        )
+    )
+
+
+def list(stub, space_id, env_id):
+    return stub.List.with_call(
+        collections_pb2.ListRequest(space_id=space_id, env_id=env_id),
+        metadata=(
+            ('authorization', f'{ACCESS_TOKEN}'),
+        )
+    )
+
+
+def update(stub, space_id, env_id, coll_id, name):
+    return stub.Update.with_call(
+        collections_pb2.UpdateRequest(
+            coll=collections_pb2.Collection(space_id=space_id, env_id=env_id, id=coll_id, name=name)),
+        metadata=(
+            ('authorization', f'{ACCESS_TOKEN}'),
+        )
+    )
+
+
+def delete(stub, space_id, env_id, coll_id):
+    return stub.Delete.with_call(
+        collections_pb2.DeleteRequest(space_id=space_id, env_id=env_id, collection_id=coll_id),
+        metadata=(
+            ('authorization', f'{ACCESS_TOKEN}'),
+        )
+    )
+
+
+def main() -> None:
+    with grpc.insecure_channel('envoy.perxis.pt.perx.ru:80') as channel:
+        stub = collections_pb2_grpc.CollectionsStub(channel)
+        print('---------- CREATE ----------')
+        response, state = create(stub, SPACE_ID, ENV_ID, 'test_coll_id', 'test collection name')
+        print(response.created, state)
+        created = response.created
+        print('---------- GET ----------')
+        response, state = get(stub, SPACE_ID, ENV_ID, created.id)
+        print(response.collection, state)
+        print('---------- LIST ----------')
+        response, state = list(stub, SPACE_ID, ENV_ID)
+        print(response.collections, state)
+        print('---------- UPDATE ----------')
+        response, state = update(stub, SPACE_ID, ENV_ID, created.id, 'new test collection name')
+        print(state)
+        print('---------- DELETE ----------')
+        response, state = delete(stub, SPACE_ID, ENV_ID, created.id)
+        print(state)
 
 
 if __name__ == '__main__':
     logging.basicConfig(level=logging.INFO)
-    asyncio.get_event_loop().run_until_complete(main())
+    main()
diff --git a/examples/environments.py b/examples/environments.py
new file mode 100644
index 0000000000000000000000000000000000000000..d4cc6c5355b0970c7c879d51aeff00737cf8591c
--- /dev/null
+++ b/examples/environments.py
@@ -0,0 +1,119 @@
+
+import logging
+
+import grpc
+
+from perxis.environments import environments_pb2, environments_pb2_grpc
+
+ACCESS_TOKEN = 'Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik5UWXhSVE5FTnprek5qSkVPRFkyTmpORk9VVXhRVEUzUmpWRVFqY3pRVE5CTjBJeE1ETTNOUSJ9.eyJodHRwczovL2hvb3AucGVyeC5ydS9pZGVudGl0eSI6eyJncm91cHMiOltdfSwibmlja25hbWUiOiJnb3NoaWstZSIsIm5hbWUiOiJHZW9yZ2l5IEV0ZXJldnNraXkiLCJwaWN0dXJlIjoiaHR0cHM6Ly9hdmF0YXJzLmdpdGh1YnVzZXJjb250ZW50LmNvbS91Lzc2NjAzMzE_dj00IiwidXBkYXRlZF9hdCI6IjIwMjEtMDQtMTlUMTg6MjU6NDYuOTYxWiIsImlzcyI6Imh0dHBzOi8vYWR3ei5hdXRoMC5jb20vIiwic3ViIjoiZ2l0aHVifDc2NjAzMzEiLCJhdWQiOiJ6d3JaaGZrd0owNlQ3MlE4ZXhOZHRFS0NxTzBja0ZpWCIsImlhdCI6MTYxODg1Njc0NywiZXhwIjoxNjE4ODkyNzQ3LCJhdXRoX3RpbWUiOjE2MTg4NTY3NDYsImF0X2hhc2giOiJoWnF4QkJUSzFrNmxobEdONXRjZXZnIiwibm9uY2UiOiJzQWFFUkJNMGI3dlprVGtZeU9xelRBT3N2S0pad0lraiJ9.Styt3ppV18Pfn_ZW3s8GPzg4nekadUjClpQXvbWZNvQb--fb8jbLsR2_pQnpjsHwO65XpEiWDinCk_cP8Qw5pqtRwhLNqueYoLPsUVKn31VyF16CSHEmRI0vaBiVPiHJmPEOHCGfKdzYlEzy73mFiSvr-oKGoXF4nkKE6a1ahimw07x8pHI5uM6JPYMMeli-1SQ7kgclFbMUhUV5hCtItKaxFfxSLDi0OjQXqGXlgMBi2k7VOfEbhMimCRnkBCsAR9kCrL1vDR8Eg3IMcVh1b-XbTX1YFxYk8B9no7qFq2Ut8PervBNSutD4rNpvtSDxGJb6fuSrxKqkAJDmB6MA9Q'
+SPACE_ID = 'c1mrvup3e6litup7tf0g'
+
+
+def create(stub, space_id, description):
+    return stub.Create.with_call(
+        environments_pb2.CreateRequest(env=environments_pb2.Environment(
+            space_id=space_id,
+            description=description
+        )),
+        metadata=(
+            ('authorization', f'{ACCESS_TOKEN}'),
+        )
+    )
+
+
+def get(stub, space_id, env_id):
+    return stub.Get.with_call(
+        environments_pb2.GetRequest(space_id=space_id, env_id=env_id),
+        metadata=(
+            ('authorization', f'{ACCESS_TOKEN}'),
+        )
+    )
+
+
+def list(stub, space_id) -> tuple:
+    return stub.List.with_call(
+        environments_pb2.ListRequest(space_id=space_id),
+        metadata=(
+            ('authorization', f'{ACCESS_TOKEN}'),
+        )
+    )
+
+
+def update(stub, space_id, env_id, description):
+    return stub.Update.with_call(
+        environments_pb2.UpdateRequest(env=environments_pb2.Environment(
+            space_id=space_id,
+            id=env_id,
+            description=description
+        )),
+        metadata=(
+            ('authorization', f'{ACCESS_TOKEN}'),
+        )
+    )
+
+
+def set_alias(stub, space_id, env_id, alias):
+    return stub.SetAlias.with_call(
+        environments_pb2.SetAliasRequest(
+            space_id=space_id,
+            env_id=env_id,
+            alias=alias
+        ),
+        metadata=(
+            ('authorization', f'{ACCESS_TOKEN}'),
+        )
+    )
+
+
+def remove_alias(stub, space_id, env_id, alias):
+    return stub.SetAlias.with_call(
+        environments_pb2.RemoveAliasRequest(
+            space_id=space_id,
+            env_id=env_id,
+            alias=alias
+        ),
+        metadata=(
+            ('authorization', f'{ACCESS_TOKEN}'),
+        )
+    )
+
+
+def delete(stub, space_id, env_id) -> tuple:
+    return stub.Delete.with_call(
+        environments_pb2.DeleteRequest(space_id=space_id, env_id=env_id),
+        metadata=(
+            ('authorization', f'{ACCESS_TOKEN}'),
+        )
+    )
+
+
+def main() -> None:
+    with grpc.insecure_channel('envoy.perxis.pt.perx.ru:80') as channel:
+        stub = environments_pb2_grpc.EnvironmentsStub(channel)
+        print('---------- CREATE ----------')
+        response, state = create(stub, SPACE_ID, 'test description')
+        created = response.created
+        print(response.created, state)
+        print('---------- GET ----------')
+        response, state = get(stub, SPACE_ID, created.id)
+        print(response.env, state)
+        print('---------- LIST ----------')
+        response, state = list(stub, SPACE_ID)
+        print(response.envs, state)
+        print('---------- UPDATE ----------')
+        response, state = update(stub, SPACE_ID, created.id, 'new test description')
+        print(state)
+        print('---------- SET ALIAS ----------')
+        response, state = set_alias(stub, SPACE_ID, created.id, 'test_alias')
+        print(state)
+        print('---------- REMOVE ALIAS ----------')
+        response, state = remove_alias(stub, SPACE_ID, created.id, 'test_alias')
+        print(state)
+        print('---------- DELETE ----------')
+        response, state = delete(stub, SPACE_ID, created.id)
+        print(state)
+
+
+if __name__ == '__main__':
+    logging.basicConfig(level=logging.INFO)
+    main()
diff --git a/examples/items.py b/examples/items.py
new file mode 100644
index 0000000000000000000000000000000000000000..1d2d58be33277d9aa792684a35119343eea333fe
--- /dev/null
+++ b/examples/items.py
@@ -0,0 +1,82 @@
+
+import logging
+
+import grpc
+
+from perxis.items import items_pb2, items_pb2_grpc
+from google.protobuf.struct_pb2 import Struct
+
+
+ACCESS_TOKEN = 'Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik5UWXhSVE5FTnprek5qSkVPRFkyTmpORk9VVXhRVEUzUmpWRVFqY3pRVE5CTjBJeE1ETTNOUSJ9.eyJodHRwczovL2hvb3AucGVyeC5ydS9pZGVudGl0eSI6eyJncm91cHMiOltdfSwibmlja25hbWUiOiJnb3NoaWstZSIsIm5hbWUiOiJHZW9yZ2l5IEV0ZXJldnNraXkiLCJwaWN0dXJlIjoiaHR0cHM6Ly9hdmF0YXJzLmdpdGh1YnVzZXJjb250ZW50LmNvbS91Lzc2NjAzMzE_dj00IiwidXBkYXRlZF9hdCI6IjIwMjEtMDQtMjBUMDc6MDM6NTAuMzM5WiIsImlzcyI6Imh0dHBzOi8vYWR3ei5hdXRoMC5jb20vIiwic3ViIjoiZ2l0aHVifDc2NjAzMzEiLCJhdWQiOiJ6d3JaaGZrd0owNlQ3MlE4ZXhOZHRFS0NxTzBja0ZpWCIsImlhdCI6MTYxODkwMjIzMCwiZXhwIjoxNjE4OTM4MjMwLCJhdXRoX3RpbWUiOjE2MTg5MDIyMzAsImF0X2hhc2giOiJNZU1FdkxBRm14N1JXZ3pDaEwxdlBBIiwibm9uY2UiOiJrTEExZDZhM0V4cjBDMlU5UVBoNG5DUkhiQ3ZvcU1TdiJ9.BqkhCwRi7_LZ0FANXU9fe_9MP0lIq7TewBo3OiSe92FXSXmyKMIEeUPnPtp0oUzf6taFgVCyQJiKrbJfpnlZYK4rVetPEWKvGpMiyv4IsQ_6Y7ZTBKdOFZrej0sKB9EFUjkBX01g4ihDyLUaz3xJYZX4qLApEPS4ubAFTuqsa_M1-rI9_8cXa3leMnQHqEOkL2Cb-N2M2uWrXYYzch8PpVyTMiBK39CA8-EJ1z8MGwjcKsqR8wryG4OWCAn84i8kt7wFAad9Tjb6YsCp1v8HlZR4cUj7u2-ztEzHDs5BNbG2dyloizBqh1XScCA261asybQgYDJDEBmqztk9mKgsVg'
+SPACE_ID = 'c1mrvup3e6litup7tf0g'
+ENV_ID = 'master'
+COLL_ID = 'test_eterevskiy'
+
+
+def create(stub, space_id, env_id, coll_id, data):
+    return stub.Create.with_call(
+        items_pb2.CreateRequest(item=items_pb2.Item(
+               space_id=space_id, env_id=env_id, collection_id=coll_id, data=data
+        )),
+        metadata=(
+            ('authorization', f'{ACCESS_TOKEN}'),
+        )
+    )
+
+
+def get(stub, space_id, env_id, coll_id, item_id):
+    return stub.Get.with_call(
+        items_pb2.GetRequest(
+            space_id=space_id, env_id=env_id, collection_id=coll_id, item_id=item_id
+        ),
+        metadata=(
+            ('authorization', f'{ACCESS_TOKEN}'),
+        )
+    )
+
+
+def find(stub, space_id, env_id, coll_id, filter=None):
+    return stub.Find.with_call(
+        items_pb2.FindRequest(space_id=space_id, env_id=env_id, collection_id=coll_id, filter=filter),
+        metadata=(
+            ('authorization', f'{ACCESS_TOKEN}'),
+        )
+    )
+
+
+def update(stub, space_id, env_id, coll_id, item_id, data):
+    return stub.Update.with_call(
+        items_pb2.UpdateRequest(
+            item=items_pb2.Item(space_id=space_id, env_id=env_id, collection_id=coll_id, id=item_id, data=data)
+        ),
+        metadata=(
+            ('authorization', f'{ACCESS_TOKEN}'),
+        )
+    )
+
+
+def main() -> None:
+    with grpc.insecure_channel('envoy.perxis.pt.perx.ru:80') as channel:
+        stub = items_pb2_grpc.ItemsStub(channel)
+        print('---------- CREATE ----------')
+        data = Struct()
+        data.update({'title': 'test'})
+        response, state = create(stub, SPACE_ID, ENV_ID, COLL_ID, data)
+        created = response.created
+        print(response.created, state)
+        print('---------- GET ----------')
+        response, state = get(stub, SPACE_ID, ENV_ID, COLL_ID, created.id)
+        print(response.item, state)
+        print('---------- FIND ----------')
+        response, state = find(stub, SPACE_ID, ENV_ID, COLL_ID)
+        print(response.items, state)
+        print('---------- UPDATE ----------')
+        data = Struct()
+        data.update({'title': 'New test title'})
+        response, state = update(stub, SPACE_ID, ENV_ID, COLL_ID, created.id, data)
+        print(state)
+
+
+if __name__ == '__main__':
+    logging.basicConfig(level=logging.INFO)
+    main()
diff --git a/examples/spaces.py b/examples/spaces.py
new file mode 100644
index 0000000000000000000000000000000000000000..13d474b1590d508f65c3c2cd9e03e9888850af41
--- /dev/null
+++ b/examples/spaces.py
@@ -0,0 +1,30 @@
+
+import logging
+
+import grpc
+
+from perxis.spaces import spaces_pb2, spaces_pb2_grpc
+
+ACCESS_TOKEN = 'Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik5UWXhSVE5FTnprek5qSkVPRFkyTmpORk9VVXhRVEUzUmpWRVFqY3pRVE5CTjBJeE1ETTNOUSJ9.eyJodHRwczovL2hvb3AucGVyeC5ydS9pZGVudGl0eSI6eyJncm91cHMiOltdfSwibmlja25hbWUiOiJnb3NoaWstZSIsIm5hbWUiOiJHZW9yZ2l5IEV0ZXJldnNraXkiLCJwaWN0dXJlIjoiaHR0cHM6Ly9hdmF0YXJzLmdpdGh1YnVzZXJjb250ZW50LmNvbS91Lzc2NjAzMzE_dj00IiwidXBkYXRlZF9hdCI6IjIwMjEtMDQtMTlUMTg6MjU6NDYuOTYxWiIsImlzcyI6Imh0dHBzOi8vYWR3ei5hdXRoMC5jb20vIiwic3ViIjoiZ2l0aHVifDc2NjAzMzEiLCJhdWQiOiJ6d3JaaGZrd0owNlQ3MlE4ZXhOZHRFS0NxTzBja0ZpWCIsImlhdCI6MTYxODg1Njc0NywiZXhwIjoxNjE4ODkyNzQ3LCJhdXRoX3RpbWUiOjE2MTg4NTY3NDYsImF0X2hhc2giOiJoWnF4QkJUSzFrNmxobEdONXRjZXZnIiwibm9uY2UiOiJzQWFFUkJNMGI3dlprVGtZeU9xelRBT3N2S0pad0lraiJ9.Styt3ppV18Pfn_ZW3s8GPzg4nekadUjClpQXvbWZNvQb--fb8jbLsR2_pQnpjsHwO65XpEiWDinCk_cP8Qw5pqtRwhLNqueYoLPsUVKn31VyF16CSHEmRI0vaBiVPiHJmPEOHCGfKdzYlEzy73mFiSvr-oKGoXF4nkKE6a1ahimw07x8pHI5uM6JPYMMeli-1SQ7kgclFbMUhUV5hCtItKaxFfxSLDi0OjQXqGXlgMBi2k7VOfEbhMimCRnkBCsAR9kCrL1vDR8Eg3IMcVh1b-XbTX1YFxYk8B9no7qFq2Ut8PervBNSutD4rNpvtSDxGJb6fuSrxKqkAJDmB6MA9Q'
+SPACE_ID = 'c1mrvup3e6litup7tf0g'
+
+
+def get(stub, space_id):
+    return stub.Get.with_call(
+        spaces_pb2.GetRequest(space_id=space_id),
+        metadata=(
+            ('authorization', f'{ACCESS_TOKEN}'),
+        ))
+
+
+def main() -> None:
+    with grpc.insecure_channel('envoy.perxis.pt.perx.ru:80') as channel:
+        stub = spaces_pb2_grpc.SpacesStub(channel)
+        print('---------- GET ----------')
+        response, state = get(stub, SPACE_ID)
+        print(response.space, state)
+
+
+if __name__ == '__main__':
+    logging.basicConfig(level=logging.INFO)
+    main()
diff --git a/perxis/auth.py b/perxis/auth.py
index fa47e5a7f8113d51af47a6aaf5a8cf96d1a2b20a..a11c983ceab34e8d6243d4fe867a7db3bf31ad8d 100644
--- a/perxis/auth.py
+++ b/perxis/auth.py
@@ -11,7 +11,7 @@ class OAuth2Plugin(grpc.AuthMetadataPlugin):
     _token = None
 
     def __init__(self, client: Type[Client], client_secret: str, token_url: str, audience: str,
-                 signature_header_key: str = 'Authorization', token_type: str = 'Bearer') -> None:
+                 signature_header_key: str = 'authorization', token_type: str = 'Bearer') -> None:
 
         self._client_secret = client_secret
         self._token_url = token_url
@@ -44,7 +44,7 @@ class OAuth2Plugin(grpc.AuthMetadataPlugin):
         if self._token is None:
             self._token = fetch_token()
 
-        if self._token.expires_at and self._token.expires_at < time.time():
+        if self._token['expires_at'] and self._token['expires_at'] < time.time():
             if 'refresh_token' in self._token:
                 self._token = refresh_token()
             else:
diff --git a/perxis/clients/clients_pb2.py b/perxis/clients/clients_pb2.py
new file mode 100644
index 0000000000000000000000000000000000000000..464c7037ea22da5bf21394dcfb4681001740f78e
--- /dev/null
+++ b/perxis/clients/clients_pb2.py
@@ -0,0 +1,842 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: clients/clients.proto
+"""Generated protocol buffer code."""
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
+from common import common_pb2 as common_dot_common__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='clients/clients.proto',
+  package='content.clients',
+  syntax='proto3',
+  serialized_options=b'Z0github.com/perxteam/perxis/proto/clients;clients',
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\x15\x63lients/clients.proto\x12\x0f\x63ontent.clients\x1a\x1bgoogle/protobuf/empty.proto\x1a\x13\x63ommon/common.proto\"\xc4\x01\n\x06\x43lient\x12\n\n\x02id\x18\x01 \x01(\t\x12\x10\n\x08space_id\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x11\n\tclient_id\x18\x04 \x01(\t\x12\x0f\n\x07\x61uth_id\x18\x05 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x06 \x01(\t\x12\x15\n\x08\x64isabled\x18\x07 \x01(\x08H\x00\x88\x01\x01\x12\x14\n\x0c\x65nvironments\x18\x08 \x03(\t\x12\x1b\n\x05rules\x18\t \x03(\x0b\x32\x0c.common.RuleB\x0b\n\t_disabled\"8\n\rCreateRequest\x12\'\n\x06\x63lient\x18\x01 \x01(\x0b\x32\x17.content.clients.Client\":\n\x0e\x43reateResponse\x12(\n\x07\x63reated\x18\x01 \x01(\x0b\x32\x17.content.clients.Client\"*\n\nGetRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\n\n\x02id\x18\x02 \x01(\t\"6\n\x0bGetResponse\x12\'\n\x06\x63lient\x18\x01 \x01(\x0b\x32\x17.content.clients.Client\"L\n\x14GetByClientIDRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x11\n\tclient_id\x18\x02 \x01(\t\x12\x0f\n\x07\x61uth_id\x18\x03 \x01(\t\"@\n\x15GetByClientIDResponse\x12\'\n\x06\x63lient\x18\x01 \x01(\x0b\x32\x17.content.clients.Client\"8\n\rUpdateRequest\x12\'\n\x06\x63lient\x18\x01 \x01(\x0b\x32\x17.content.clients.Client\"\x1f\n\x0bListRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\"8\n\x0cListResponse\x12(\n\x07\x63lients\x18\x01 \x03(\x0b\x32\x17.content.clients.Client\"-\n\rDeleteRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\n\n\x02id\x18\x02 \x01(\t\"=\n\rEnableRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\n\n\x02id\x18\x02 \x01(\t\x12\x0e\n\x06\x65nable\x18\x03 \x01(\x08\"J\n\x0eSetRuleRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\n\n\x02id\x18\x02 \x01(\t\x12\x1a\n\x04rule\x18\x03 \x01(\x0b\x32\x0c.common.Rule\"B\n\x11RemoveRuleRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\n\n\x02id\x18\x02 \x01(\t\x12\x0f\n\x07rule_id\x18\x03 \x01(\t2\xa1\x05\n\x07\x43lients\x12K\n\x06\x43reate\x12\x1e.content.clients.CreateRequest\x1a\x1f.content.clients.CreateResponse\"\x00\x12\x42\n\x03Get\x12\x1b.content.clients.GetRequest\x1a\x1c.content.clients.GetResponse\"\x00\x12`\n\rGetByClientID\x12%.content.clients.GetByClientIDRequest\x1a&.content.clients.GetByClientIDResponse\"\x00\x12\x42\n\x06Update\x12\x1e.content.clients.UpdateRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x45\n\x04List\x12\x1c.content.clients.ListRequest\x1a\x1d.content.clients.ListResponse\"\x00\x12\x42\n\x06\x44\x65lete\x12\x1e.content.clients.DeleteRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x42\n\x06\x45nable\x12\x1e.content.clients.EnableRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x44\n\x07SetRule\x12\x1f.content.clients.SetRuleRequest\x1a\x16.google.protobuf.Empty\"\x00\x12J\n\nRemoveRule\x12\".content.clients.RemoveRuleRequest\x1a\x16.google.protobuf.Empty\"\x00\x42\x32Z0github.com/perxteam/perxis/proto/clients;clientsb\x06proto3'
+  ,
+  dependencies=[google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,common_dot_common__pb2.DESCRIPTOR,])
+
+
+
+
+_CLIENT = _descriptor.Descriptor(
+  name='Client',
+  full_name='content.clients.Client',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='id', full_name='content.clients.Client.id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='space_id', full_name='content.clients.Client.space_id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='name', full_name='content.clients.Client.name', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='content.clients.Client.client_id', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='auth_id', full_name='content.clients.Client.auth_id', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='description', full_name='content.clients.Client.description', index=5,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='disabled', full_name='content.clients.Client.disabled', index=6,
+      number=7, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='environments', full_name='content.clients.Client.environments', index=7,
+      number=8, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='rules', full_name='content.clients.Client.rules', index=8,
+      number=9, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+    _descriptor.OneofDescriptor(
+      name='_disabled', full_name='content.clients.Client._disabled',
+      index=0, containing_type=None,
+      create_key=_descriptor._internal_create_key,
+    fields=[]),
+  ],
+  serialized_start=93,
+  serialized_end=289,
+)
+
+
+_CREATEREQUEST = _descriptor.Descriptor(
+  name='CreateRequest',
+  full_name='content.clients.CreateRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='client', full_name='content.clients.CreateRequest.client', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=291,
+  serialized_end=347,
+)
+
+
+_CREATERESPONSE = _descriptor.Descriptor(
+  name='CreateResponse',
+  full_name='content.clients.CreateResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='created', full_name='content.clients.CreateResponse.created', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=349,
+  serialized_end=407,
+)
+
+
+_GETREQUEST = _descriptor.Descriptor(
+  name='GetRequest',
+  full_name='content.clients.GetRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='space_id', full_name='content.clients.GetRequest.space_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='id', full_name='content.clients.GetRequest.id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=409,
+  serialized_end=451,
+)
+
+
+_GETRESPONSE = _descriptor.Descriptor(
+  name='GetResponse',
+  full_name='content.clients.GetResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='client', full_name='content.clients.GetResponse.client', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=453,
+  serialized_end=507,
+)
+
+
+_GETBYCLIENTIDREQUEST = _descriptor.Descriptor(
+  name='GetByClientIDRequest',
+  full_name='content.clients.GetByClientIDRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='space_id', full_name='content.clients.GetByClientIDRequest.space_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='client_id', full_name='content.clients.GetByClientIDRequest.client_id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='auth_id', full_name='content.clients.GetByClientIDRequest.auth_id', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=509,
+  serialized_end=585,
+)
+
+
+_GETBYCLIENTIDRESPONSE = _descriptor.Descriptor(
+  name='GetByClientIDResponse',
+  full_name='content.clients.GetByClientIDResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='client', full_name='content.clients.GetByClientIDResponse.client', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=587,
+  serialized_end=651,
+)
+
+
+_UPDATEREQUEST = _descriptor.Descriptor(
+  name='UpdateRequest',
+  full_name='content.clients.UpdateRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='client', full_name='content.clients.UpdateRequest.client', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=653,
+  serialized_end=709,
+)
+
+
+_LISTREQUEST = _descriptor.Descriptor(
+  name='ListRequest',
+  full_name='content.clients.ListRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='space_id', full_name='content.clients.ListRequest.space_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=711,
+  serialized_end=742,
+)
+
+
+_LISTRESPONSE = _descriptor.Descriptor(
+  name='ListResponse',
+  full_name='content.clients.ListResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='clients', full_name='content.clients.ListResponse.clients', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=744,
+  serialized_end=800,
+)
+
+
+_DELETEREQUEST = _descriptor.Descriptor(
+  name='DeleteRequest',
+  full_name='content.clients.DeleteRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='space_id', full_name='content.clients.DeleteRequest.space_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='id', full_name='content.clients.DeleteRequest.id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=802,
+  serialized_end=847,
+)
+
+
+_ENABLEREQUEST = _descriptor.Descriptor(
+  name='EnableRequest',
+  full_name='content.clients.EnableRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='space_id', full_name='content.clients.EnableRequest.space_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='id', full_name='content.clients.EnableRequest.id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='enable', full_name='content.clients.EnableRequest.enable', index=2,
+      number=3, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=849,
+  serialized_end=910,
+)
+
+
+_SETRULEREQUEST = _descriptor.Descriptor(
+  name='SetRuleRequest',
+  full_name='content.clients.SetRuleRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='space_id', full_name='content.clients.SetRuleRequest.space_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='id', full_name='content.clients.SetRuleRequest.id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='rule', full_name='content.clients.SetRuleRequest.rule', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=912,
+  serialized_end=986,
+)
+
+
+_REMOVERULEREQUEST = _descriptor.Descriptor(
+  name='RemoveRuleRequest',
+  full_name='content.clients.RemoveRuleRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='space_id', full_name='content.clients.RemoveRuleRequest.space_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='id', full_name='content.clients.RemoveRuleRequest.id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='rule_id', full_name='content.clients.RemoveRuleRequest.rule_id', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=988,
+  serialized_end=1054,
+)
+
+_CLIENT.fields_by_name['rules'].message_type = common_dot_common__pb2._RULE
+_CLIENT.oneofs_by_name['_disabled'].fields.append(
+  _CLIENT.fields_by_name['disabled'])
+_CLIENT.fields_by_name['disabled'].containing_oneof = _CLIENT.oneofs_by_name['_disabled']
+_CREATEREQUEST.fields_by_name['client'].message_type = _CLIENT
+_CREATERESPONSE.fields_by_name['created'].message_type = _CLIENT
+_GETRESPONSE.fields_by_name['client'].message_type = _CLIENT
+_GETBYCLIENTIDRESPONSE.fields_by_name['client'].message_type = _CLIENT
+_UPDATEREQUEST.fields_by_name['client'].message_type = _CLIENT
+_LISTRESPONSE.fields_by_name['clients'].message_type = _CLIENT
+_SETRULEREQUEST.fields_by_name['rule'].message_type = common_dot_common__pb2._RULE
+DESCRIPTOR.message_types_by_name['Client'] = _CLIENT
+DESCRIPTOR.message_types_by_name['CreateRequest'] = _CREATEREQUEST
+DESCRIPTOR.message_types_by_name['CreateResponse'] = _CREATERESPONSE
+DESCRIPTOR.message_types_by_name['GetRequest'] = _GETREQUEST
+DESCRIPTOR.message_types_by_name['GetResponse'] = _GETRESPONSE
+DESCRIPTOR.message_types_by_name['GetByClientIDRequest'] = _GETBYCLIENTIDREQUEST
+DESCRIPTOR.message_types_by_name['GetByClientIDResponse'] = _GETBYCLIENTIDRESPONSE
+DESCRIPTOR.message_types_by_name['UpdateRequest'] = _UPDATEREQUEST
+DESCRIPTOR.message_types_by_name['ListRequest'] = _LISTREQUEST
+DESCRIPTOR.message_types_by_name['ListResponse'] = _LISTRESPONSE
+DESCRIPTOR.message_types_by_name['DeleteRequest'] = _DELETEREQUEST
+DESCRIPTOR.message_types_by_name['EnableRequest'] = _ENABLEREQUEST
+DESCRIPTOR.message_types_by_name['SetRuleRequest'] = _SETRULEREQUEST
+DESCRIPTOR.message_types_by_name['RemoveRuleRequest'] = _REMOVERULEREQUEST
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+Client = _reflection.GeneratedProtocolMessageType('Client', (_message.Message,), {
+  'DESCRIPTOR' : _CLIENT,
+  '__module__' : 'clients.clients_pb2'
+  # @@protoc_insertion_point(class_scope:content.clients.Client)
+  })
+_sym_db.RegisterMessage(Client)
+
+CreateRequest = _reflection.GeneratedProtocolMessageType('CreateRequest', (_message.Message,), {
+  'DESCRIPTOR' : _CREATEREQUEST,
+  '__module__' : 'clients.clients_pb2'
+  # @@protoc_insertion_point(class_scope:content.clients.CreateRequest)
+  })
+_sym_db.RegisterMessage(CreateRequest)
+
+CreateResponse = _reflection.GeneratedProtocolMessageType('CreateResponse', (_message.Message,), {
+  'DESCRIPTOR' : _CREATERESPONSE,
+  '__module__' : 'clients.clients_pb2'
+  # @@protoc_insertion_point(class_scope:content.clients.CreateResponse)
+  })
+_sym_db.RegisterMessage(CreateResponse)
+
+GetRequest = _reflection.GeneratedProtocolMessageType('GetRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETREQUEST,
+  '__module__' : 'clients.clients_pb2'
+  # @@protoc_insertion_point(class_scope:content.clients.GetRequest)
+  })
+_sym_db.RegisterMessage(GetRequest)
+
+GetResponse = _reflection.GeneratedProtocolMessageType('GetResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GETRESPONSE,
+  '__module__' : 'clients.clients_pb2'
+  # @@protoc_insertion_point(class_scope:content.clients.GetResponse)
+  })
+_sym_db.RegisterMessage(GetResponse)
+
+GetByClientIDRequest = _reflection.GeneratedProtocolMessageType('GetByClientIDRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETBYCLIENTIDREQUEST,
+  '__module__' : 'clients.clients_pb2'
+  # @@protoc_insertion_point(class_scope:content.clients.GetByClientIDRequest)
+  })
+_sym_db.RegisterMessage(GetByClientIDRequest)
+
+GetByClientIDResponse = _reflection.GeneratedProtocolMessageType('GetByClientIDResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GETBYCLIENTIDRESPONSE,
+  '__module__' : 'clients.clients_pb2'
+  # @@protoc_insertion_point(class_scope:content.clients.GetByClientIDResponse)
+  })
+_sym_db.RegisterMessage(GetByClientIDResponse)
+
+UpdateRequest = _reflection.GeneratedProtocolMessageType('UpdateRequest', (_message.Message,), {
+  'DESCRIPTOR' : _UPDATEREQUEST,
+  '__module__' : 'clients.clients_pb2'
+  # @@protoc_insertion_point(class_scope:content.clients.UpdateRequest)
+  })
+_sym_db.RegisterMessage(UpdateRequest)
+
+ListRequest = _reflection.GeneratedProtocolMessageType('ListRequest', (_message.Message,), {
+  'DESCRIPTOR' : _LISTREQUEST,
+  '__module__' : 'clients.clients_pb2'
+  # @@protoc_insertion_point(class_scope:content.clients.ListRequest)
+  })
+_sym_db.RegisterMessage(ListRequest)
+
+ListResponse = _reflection.GeneratedProtocolMessageType('ListResponse', (_message.Message,), {
+  'DESCRIPTOR' : _LISTRESPONSE,
+  '__module__' : 'clients.clients_pb2'
+  # @@protoc_insertion_point(class_scope:content.clients.ListResponse)
+  })
+_sym_db.RegisterMessage(ListResponse)
+
+DeleteRequest = _reflection.GeneratedProtocolMessageType('DeleteRequest', (_message.Message,), {
+  'DESCRIPTOR' : _DELETEREQUEST,
+  '__module__' : 'clients.clients_pb2'
+  # @@protoc_insertion_point(class_scope:content.clients.DeleteRequest)
+  })
+_sym_db.RegisterMessage(DeleteRequest)
+
+EnableRequest = _reflection.GeneratedProtocolMessageType('EnableRequest', (_message.Message,), {
+  'DESCRIPTOR' : _ENABLEREQUEST,
+  '__module__' : 'clients.clients_pb2'
+  # @@protoc_insertion_point(class_scope:content.clients.EnableRequest)
+  })
+_sym_db.RegisterMessage(EnableRequest)
+
+SetRuleRequest = _reflection.GeneratedProtocolMessageType('SetRuleRequest', (_message.Message,), {
+  'DESCRIPTOR' : _SETRULEREQUEST,
+  '__module__' : 'clients.clients_pb2'
+  # @@protoc_insertion_point(class_scope:content.clients.SetRuleRequest)
+  })
+_sym_db.RegisterMessage(SetRuleRequest)
+
+RemoveRuleRequest = _reflection.GeneratedProtocolMessageType('RemoveRuleRequest', (_message.Message,), {
+  'DESCRIPTOR' : _REMOVERULEREQUEST,
+  '__module__' : 'clients.clients_pb2'
+  # @@protoc_insertion_point(class_scope:content.clients.RemoveRuleRequest)
+  })
+_sym_db.RegisterMessage(RemoveRuleRequest)
+
+
+DESCRIPTOR._options = None
+
+_CLIENTS = _descriptor.ServiceDescriptor(
+  name='Clients',
+  full_name='content.clients.Clients',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_start=1057,
+  serialized_end=1730,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='Create',
+    full_name='content.clients.Clients.Create',
+    index=0,
+    containing_service=None,
+    input_type=_CREATEREQUEST,
+    output_type=_CREATERESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='Get',
+    full_name='content.clients.Clients.Get',
+    index=1,
+    containing_service=None,
+    input_type=_GETREQUEST,
+    output_type=_GETRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetByClientID',
+    full_name='content.clients.Clients.GetByClientID',
+    index=2,
+    containing_service=None,
+    input_type=_GETBYCLIENTIDREQUEST,
+    output_type=_GETBYCLIENTIDRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='Update',
+    full_name='content.clients.Clients.Update',
+    index=3,
+    containing_service=None,
+    input_type=_UPDATEREQUEST,
+    output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='List',
+    full_name='content.clients.Clients.List',
+    index=4,
+    containing_service=None,
+    input_type=_LISTREQUEST,
+    output_type=_LISTRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='Delete',
+    full_name='content.clients.Clients.Delete',
+    index=5,
+    containing_service=None,
+    input_type=_DELETEREQUEST,
+    output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='Enable',
+    full_name='content.clients.Clients.Enable',
+    index=6,
+    containing_service=None,
+    input_type=_ENABLEREQUEST,
+    output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetRule',
+    full_name='content.clients.Clients.SetRule',
+    index=7,
+    containing_service=None,
+    input_type=_SETRULEREQUEST,
+    output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveRule',
+    full_name='content.clients.Clients.RemoveRule',
+    index=8,
+    containing_service=None,
+    input_type=_REMOVERULEREQUEST,
+    output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_CLIENTS)
+
+DESCRIPTOR.services_by_name['Clients'] = _CLIENTS
+
+# @@protoc_insertion_point(module_scope)
diff --git a/perxis/clients/clients_pb2_grpc.py b/perxis/clients/clients_pb2_grpc.py
new file mode 100644
index 0000000000000000000000000000000000000000..89b686c3c0c28572b17c519eafc8a7bf0d4951e0
--- /dev/null
+++ b/perxis/clients/clients_pb2_grpc.py
@@ -0,0 +1,340 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+"""Client and server classes corresponding to protobuf-defined services."""
+import grpc
+
+from clients import clients_pb2 as clients_dot_clients__pb2
+from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
+
+
+class ClientsStub(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def __init__(self, channel):
+        """Constructor.
+
+        Args:
+            channel: A grpc.Channel.
+        """
+        self.Create = channel.unary_unary(
+                '/content.clients.Clients/Create',
+                request_serializer=clients_dot_clients__pb2.CreateRequest.SerializeToString,
+                response_deserializer=clients_dot_clients__pb2.CreateResponse.FromString,
+                )
+        self.Get = channel.unary_unary(
+                '/content.clients.Clients/Get',
+                request_serializer=clients_dot_clients__pb2.GetRequest.SerializeToString,
+                response_deserializer=clients_dot_clients__pb2.GetResponse.FromString,
+                )
+        self.GetByClientID = channel.unary_unary(
+                '/content.clients.Clients/GetByClientID',
+                request_serializer=clients_dot_clients__pb2.GetByClientIDRequest.SerializeToString,
+                response_deserializer=clients_dot_clients__pb2.GetByClientIDResponse.FromString,
+                )
+        self.Update = channel.unary_unary(
+                '/content.clients.Clients/Update',
+                request_serializer=clients_dot_clients__pb2.UpdateRequest.SerializeToString,
+                response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+                )
+        self.List = channel.unary_unary(
+                '/content.clients.Clients/List',
+                request_serializer=clients_dot_clients__pb2.ListRequest.SerializeToString,
+                response_deserializer=clients_dot_clients__pb2.ListResponse.FromString,
+                )
+        self.Delete = channel.unary_unary(
+                '/content.clients.Clients/Delete',
+                request_serializer=clients_dot_clients__pb2.DeleteRequest.SerializeToString,
+                response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+                )
+        self.Enable = channel.unary_unary(
+                '/content.clients.Clients/Enable',
+                request_serializer=clients_dot_clients__pb2.EnableRequest.SerializeToString,
+                response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+                )
+        self.SetRule = channel.unary_unary(
+                '/content.clients.Clients/SetRule',
+                request_serializer=clients_dot_clients__pb2.SetRuleRequest.SerializeToString,
+                response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+                )
+        self.RemoveRule = channel.unary_unary(
+                '/content.clients.Clients/RemoveRule',
+                request_serializer=clients_dot_clients__pb2.RemoveRuleRequest.SerializeToString,
+                response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+                )
+
+
+class ClientsServicer(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def Create(self, request, context):
+        """Create - создает клиента (приложение) для работы с API
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def Get(self, request, context):
+        """Get - возвращает клиента по id
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def GetByClientID(self, request, context):
+        """GetByClientID - возвращает клиента по clientId системы авторизации
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def Update(self, request, context):
+        """Update - обновляет параметры клиента
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def List(self, request, context):
+        """List - возвращает список клиентов созданных в пространстве
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def Delete(self, request, context):
+        """Delete - удаляет указанного клиента из пространстве
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def Enable(self, request, context):
+        """Enable - активирует/деактивирует клиента. Клиент не сможет обращаться к API платформы
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def SetRule(self, request, context):
+        """SetRule - добавляет клиенту правила доступа к API
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def RemoveRule(self, request, context):
+        """SetRule - удаляет правилу с указанным Id
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+
+def add_ClientsServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+            'Create': grpc.unary_unary_rpc_method_handler(
+                    servicer.Create,
+                    request_deserializer=clients_dot_clients__pb2.CreateRequest.FromString,
+                    response_serializer=clients_dot_clients__pb2.CreateResponse.SerializeToString,
+            ),
+            'Get': grpc.unary_unary_rpc_method_handler(
+                    servicer.Get,
+                    request_deserializer=clients_dot_clients__pb2.GetRequest.FromString,
+                    response_serializer=clients_dot_clients__pb2.GetResponse.SerializeToString,
+            ),
+            'GetByClientID': grpc.unary_unary_rpc_method_handler(
+                    servicer.GetByClientID,
+                    request_deserializer=clients_dot_clients__pb2.GetByClientIDRequest.FromString,
+                    response_serializer=clients_dot_clients__pb2.GetByClientIDResponse.SerializeToString,
+            ),
+            'Update': grpc.unary_unary_rpc_method_handler(
+                    servicer.Update,
+                    request_deserializer=clients_dot_clients__pb2.UpdateRequest.FromString,
+                    response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
+            ),
+            'List': grpc.unary_unary_rpc_method_handler(
+                    servicer.List,
+                    request_deserializer=clients_dot_clients__pb2.ListRequest.FromString,
+                    response_serializer=clients_dot_clients__pb2.ListResponse.SerializeToString,
+            ),
+            'Delete': grpc.unary_unary_rpc_method_handler(
+                    servicer.Delete,
+                    request_deserializer=clients_dot_clients__pb2.DeleteRequest.FromString,
+                    response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
+            ),
+            'Enable': grpc.unary_unary_rpc_method_handler(
+                    servicer.Enable,
+                    request_deserializer=clients_dot_clients__pb2.EnableRequest.FromString,
+                    response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
+            ),
+            'SetRule': grpc.unary_unary_rpc_method_handler(
+                    servicer.SetRule,
+                    request_deserializer=clients_dot_clients__pb2.SetRuleRequest.FromString,
+                    response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
+            ),
+            'RemoveRule': grpc.unary_unary_rpc_method_handler(
+                    servicer.RemoveRule,
+                    request_deserializer=clients_dot_clients__pb2.RemoveRuleRequest.FromString,
+                    response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
+            ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+            'content.clients.Clients', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+ # This class is part of an EXPERIMENTAL API.
+class Clients(object):
+    """Missing associated documentation comment in .proto file."""
+
+    @staticmethod
+    def Create(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.clients.Clients/Create',
+            clients_dot_clients__pb2.CreateRequest.SerializeToString,
+            clients_dot_clients__pb2.CreateResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def Get(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.clients.Clients/Get',
+            clients_dot_clients__pb2.GetRequest.SerializeToString,
+            clients_dot_clients__pb2.GetResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def GetByClientID(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.clients.Clients/GetByClientID',
+            clients_dot_clients__pb2.GetByClientIDRequest.SerializeToString,
+            clients_dot_clients__pb2.GetByClientIDResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def Update(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.clients.Clients/Update',
+            clients_dot_clients__pb2.UpdateRequest.SerializeToString,
+            google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def List(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.clients.Clients/List',
+            clients_dot_clients__pb2.ListRequest.SerializeToString,
+            clients_dot_clients__pb2.ListResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def Delete(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.clients.Clients/Delete',
+            clients_dot_clients__pb2.DeleteRequest.SerializeToString,
+            google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def Enable(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.clients.Clients/Enable',
+            clients_dot_clients__pb2.EnableRequest.SerializeToString,
+            google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def SetRule(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.clients.Clients/SetRule',
+            clients_dot_clients__pb2.SetRuleRequest.SerializeToString,
+            google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def RemoveRule(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.clients.Clients/RemoveRule',
+            clients_dot_clients__pb2.RemoveRuleRequest.SerializeToString,
+            google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/perxis/collaborators/collaborators_pb2.py b/perxis/collaborators/collaborators_pb2.py
index 0b3dcd8d8463a6ac7f303db13d7e888e87304022..149e3c094e34980703e17b71fa95ee2cecc60d9d 100644
--- a/perxis/collaborators/collaborators_pb2.py
+++ b/perxis/collaborators/collaborators_pb2.py
@@ -12,6 +12,7 @@ _sym_db = _symbol_database.Default()
 
 
 from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
+from common import common_pb2 as common_dot_common__pb2
 
 
 DESCRIPTOR = _descriptor.FileDescriptor(
@@ -20,59 +21,13 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=b'Z<github.com/perxteam/perxis/proto/collaborators;collaborators',
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n!collaborators/collaborators.proto\x12\x15\x63ontent.collaborators\x1a\x1bgoogle/protobuf/empty.proto\"?\n\x0c\x43ollaborator\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0f\n\x07user_id\x18\x02 \x01(\t\x12\x0c\n\x04role\x18\x03 \x01(\t\"=\n\nSetRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0f\n\x07user_id\x18\x02 \x01(\t\x12\x0c\n\x04role\x18\x03 \x01(\t\"/\n\nGetRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0f\n\x07user_id\x18\x02 \x01(\t\"\x1b\n\x0bGetResponse\x12\x0c\n\x04role\x18\x03 \x01(\t\"2\n\rRemoveRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0f\n\x07user_id\x18\x02 \x01(\t\",\n\x18ListCollaboratorsRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\"W\n\x19ListCollaboratorsResponse\x12:\n\rcollaborators\x18\x01 \x03(\x0b\x32#.content.collaborators.Collaborator\"$\n\x11ListSpacesRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t\"I\n\x12ListSpacesResponse\x12\x33\n\x06spaces\x18\x01 \x03(\x0b\x32#.content.collaborators.Collaborator2\xcc\x03\n\rCollaborators\x12\x42\n\x03Set\x12!.content.collaborators.SetRequest\x1a\x16.google.protobuf.Empty\"\x00\x12N\n\x03Get\x12!.content.collaborators.GetRequest\x1a\".content.collaborators.GetResponse\"\x00\x12H\n\x06Remove\x12$.content.collaborators.RemoveRequest\x1a\x16.google.protobuf.Empty\"\x00\x12x\n\x11ListCollaborators\x12/.content.collaborators.ListCollaboratorsRequest\x1a\x30.content.collaborators.ListCollaboratorsResponse\"\x00\x12\x63\n\nListSpaces\x12(.content.collaborators.ListSpacesRequest\x1a).content.collaborators.ListSpacesResponse\"\x00\x42>Z<github.com/perxteam/perxis/proto/collaborators;collaboratorsb\x06proto3'
+  serialized_pb=b'\n!collaborators/collaborators.proto\x12\x15\x63ontent.collaborators\x1a\x1bgoogle/protobuf/empty.proto\x1a\x13\x63ommon/common.proto\"=\n\nSetRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0f\n\x07user_id\x18\x02 \x01(\t\x12\x0c\n\x04role\x18\x03 \x01(\t\"/\n\nGetRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0f\n\x07user_id\x18\x02 \x01(\t\"\x1b\n\x0bGetResponse\x12\x0c\n\x04role\x18\x03 \x01(\t\"2\n\rRemoveRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0f\n\x07user_id\x18\x02 \x01(\t\",\n\x18ListCollaboratorsRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\"H\n\x19ListCollaboratorsResponse\x12+\n\rcollaborators\x18\x01 \x03(\x0b\x32\x14.common.Collaborator\"$\n\x11ListSpacesRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t\":\n\x12ListSpacesResponse\x12$\n\x06spaces\x18\x01 \x03(\x0b\x32\x14.common.Collaborator2\xcc\x03\n\rCollaborators\x12\x42\n\x03Set\x12!.content.collaborators.SetRequest\x1a\x16.google.protobuf.Empty\"\x00\x12N\n\x03Get\x12!.content.collaborators.GetRequest\x1a\".content.collaborators.GetResponse\"\x00\x12H\n\x06Remove\x12$.content.collaborators.RemoveRequest\x1a\x16.google.protobuf.Empty\"\x00\x12x\n\x11ListCollaborators\x12/.content.collaborators.ListCollaboratorsRequest\x1a\x30.content.collaborators.ListCollaboratorsResponse\"\x00\x12\x63\n\nListSpaces\x12(.content.collaborators.ListSpacesRequest\x1a).content.collaborators.ListSpacesResponse\"\x00\x42>Z<github.com/perxteam/perxis/proto/collaborators;collaboratorsb\x06proto3'
   ,
-  dependencies=[google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,])
+  dependencies=[google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,common_dot_common__pb2.DESCRIPTOR,])
 
 
 
 
-_COLLABORATOR = _descriptor.Descriptor(
-  name='Collaborator',
-  full_name='content.collaborators.Collaborator',
-  filename=None,
-  file=DESCRIPTOR,
-  containing_type=None,
-  create_key=_descriptor._internal_create_key,
-  fields=[
-    _descriptor.FieldDescriptor(
-      name='space_id', full_name='content.collaborators.Collaborator.space_id', index=0,
-      number=1, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='user_id', full_name='content.collaborators.Collaborator.user_id', index=1,
-      number=2, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='role', full_name='content.collaborators.Collaborator.role', index=2,
-      number=3, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-  ],
-  extensions=[
-  ],
-  nested_types=[],
-  enum_types=[
-  ],
-  serialized_options=None,
-  is_extendable=False,
-  syntax='proto3',
-  extension_ranges=[],
-  oneofs=[
-  ],
-  serialized_start=89,
-  serialized_end=152,
-)
-
-
 _SETREQUEST = _descriptor.Descriptor(
   name='SetRequest',
   full_name='content.collaborators.SetRequest',
@@ -114,8 +69,8 @@ _SETREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=154,
-  serialized_end=215,
+  serialized_start=110,
+  serialized_end=171,
 )
 
 
@@ -153,8 +108,8 @@ _GETREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=217,
-  serialized_end=264,
+  serialized_start=173,
+  serialized_end=220,
 )
 
 
@@ -185,8 +140,8 @@ _GETRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=266,
-  serialized_end=293,
+  serialized_start=222,
+  serialized_end=249,
 )
 
 
@@ -224,8 +179,8 @@ _REMOVEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=295,
-  serialized_end=345,
+  serialized_start=251,
+  serialized_end=301,
 )
 
 
@@ -256,8 +211,8 @@ _LISTCOLLABORATORSREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=347,
-  serialized_end=391,
+  serialized_start=303,
+  serialized_end=347,
 )
 
 
@@ -288,8 +243,8 @@ _LISTCOLLABORATORSRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=393,
-  serialized_end=480,
+  serialized_start=349,
+  serialized_end=421,
 )
 
 
@@ -320,8 +275,8 @@ _LISTSPACESREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=482,
-  serialized_end=518,
+  serialized_start=423,
+  serialized_end=459,
 )
 
 
@@ -352,13 +307,12 @@ _LISTSPACESRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=520,
-  serialized_end=593,
+  serialized_start=461,
+  serialized_end=519,
 )
 
-_LISTCOLLABORATORSRESPONSE.fields_by_name['collaborators'].message_type = _COLLABORATOR
-_LISTSPACESRESPONSE.fields_by_name['spaces'].message_type = _COLLABORATOR
-DESCRIPTOR.message_types_by_name['Collaborator'] = _COLLABORATOR
+_LISTCOLLABORATORSRESPONSE.fields_by_name['collaborators'].message_type = common_dot_common__pb2._COLLABORATOR
+_LISTSPACESRESPONSE.fields_by_name['spaces'].message_type = common_dot_common__pb2._COLLABORATOR
 DESCRIPTOR.message_types_by_name['SetRequest'] = _SETREQUEST
 DESCRIPTOR.message_types_by_name['GetRequest'] = _GETREQUEST
 DESCRIPTOR.message_types_by_name['GetResponse'] = _GETRESPONSE
@@ -369,13 +323,6 @@ DESCRIPTOR.message_types_by_name['ListSpacesRequest'] = _LISTSPACESREQUEST
 DESCRIPTOR.message_types_by_name['ListSpacesResponse'] = _LISTSPACESRESPONSE
 _sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
-Collaborator = _reflection.GeneratedProtocolMessageType('Collaborator', (_message.Message,), {
-  'DESCRIPTOR' : _COLLABORATOR,
-  '__module__' : 'collaborators.collaborators_pb2'
-  # @@protoc_insertion_point(class_scope:content.collaborators.Collaborator)
-  })
-_sym_db.RegisterMessage(Collaborator)
-
 SetRequest = _reflection.GeneratedProtocolMessageType('SetRequest', (_message.Message,), {
   'DESCRIPTOR' : _SETREQUEST,
   '__module__' : 'collaborators.collaborators_pb2'
@@ -442,8 +389,8 @@ _COLLABORATORS = _descriptor.ServiceDescriptor(
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=596,
-  serialized_end=1056,
+  serialized_start=522,
+  serialized_end=982,
   methods=[
   _descriptor.MethodDescriptor(
     name='Set',
diff --git a/perxis/collections_perxis/collections_pb2.py b/perxis/collections_perxis/collections_pb2.py
index 0cc8c428cff22156633fea6b98f49f76aaa4ef96..c7c6de705d42fdd172614423ee338081ce329689 100644
--- a/perxis/collections_perxis/collections_pb2.py
+++ b/perxis/collections_perxis/collections_pb2.py
@@ -12,7 +12,6 @@ _sym_db = _symbol_database.Default()
 
 
 from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
-from google.protobuf import wrappers_pb2 as google_dot_protobuf_dot_wrappers__pb2
 
 
 DESCRIPTOR = _descriptor.FileDescriptor(
@@ -21,9 +20,9 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=b'Z8github.com/perxteam/perxis/proto/collections;collections',
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n$collections_perxis/collections.proto\x12\x13\x63ontent.collections\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1egoogle/protobuf/wrappers.proto\"x\n\nCollection\x12\n\n\x02id\x18\x01 \x01(\t\x12\x10\n\x08space_id\x18\x02 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x03 \x01(\t\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\x0e\n\x06single\x18\x05 \x01(\x08\x12\x0e\n\x06system\x18\x06 \x01(\x08\x12\x0e\n\x06schema\x18\x07 \x01(\t\"\x86\x01\n\rCreateRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\x0e\n\x06single\x18\x05 \x01(\x08\x12\x0e\n\x06system\x18\x06 \x01(\x08\x12\x0e\n\x06schema\x18\x07 \x01(\t\"E\n\x0e\x43reateResponse\x12\x33\n\ncollection\x18\x01 \x01(\x0b\x32\x1f.content.collections.Collection\"E\n\nGetRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\"B\n\x0bGetResponse\x12\x33\n\ncollection\x18\x01 \x01(\x0b\x32\x1f.content.collections.Collection\"/\n\x0bListRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\"D\n\x0cListResponse\x12\x34\n\x0b\x63ollections\x18\x01 \x03(\x0b\x32\x1f.content.collections.Collection\"\x92\x01\n\rUpdateRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x0c\n\x04name\x18\x04 \x01(\t\x12*\n\x06single\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x0e\n\x06schema\x18\x06 \x01(\t\"H\n\rDeleteRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t2\x8d\x03\n\x0b\x43ollections\x12S\n\x06\x43reate\x12\".content.collections.CreateRequest\x1a#.content.collections.CreateResponse\"\x00\x12J\n\x03Get\x12\x1f.content.collections.GetRequest\x1a .content.collections.GetResponse\"\x00\x12M\n\x04List\x12 .content.collections.ListRequest\x1a!.content.collections.ListResponse\"\x00\x12\x46\n\x06Update\x12\".content.collections.UpdateRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x46\n\x06\x44\x65lete\x12\".content.collections.DeleteRequest\x1a\x16.google.protobuf.Empty\"\x00\x42:Z8github.com/perxteam/perxis/proto/collections;collectionsb\x06proto3'
+  serialized_pb=b'\n$collections_perxis/collections.proto\x12\x13\x63ontent.collections\x1a\x1bgoogle/protobuf/empty.proto\"\x98\x01\n\nCollection\x12\n\n\x02id\x18\x01 \x01(\t\x12\x10\n\x08space_id\x18\x02 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x03 \x01(\t\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\x13\n\x06single\x18\x05 \x01(\x08H\x00\x88\x01\x01\x12\x13\n\x06system\x18\x06 \x01(\x08H\x01\x88\x01\x01\x12\x0e\n\x06schema\x18\x07 \x01(\tB\t\n\x07_singleB\t\n\x07_system\">\n\rCreateRequest\x12-\n\x04\x63oll\x18\x01 \x01(\x0b\x32\x1f.content.collections.Collection\"B\n\x0e\x43reateResponse\x12\x30\n\x07\x63reated\x18\x01 \x01(\x0b\x32\x1f.content.collections.Collection\"E\n\nGetRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\"B\n\x0bGetResponse\x12\x33\n\ncollection\x18\x01 \x01(\x0b\x32\x1f.content.collections.Collection\"/\n\x0bListRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\"D\n\x0cListResponse\x12\x34\n\x0b\x63ollections\x18\x01 \x03(\x0b\x32\x1f.content.collections.Collection\">\n\rUpdateRequest\x12-\n\x04\x63oll\x18\x01 \x01(\x0b\x32\x1f.content.collections.Collection\"H\n\rDeleteRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t2\x8d\x03\n\x0b\x43ollections\x12S\n\x06\x43reate\x12\".content.collections.CreateRequest\x1a#.content.collections.CreateResponse\"\x00\x12J\n\x03Get\x12\x1f.content.collections.GetRequest\x1a .content.collections.GetResponse\"\x00\x12M\n\x04List\x12 .content.collections.ListRequest\x1a!.content.collections.ListResponse\"\x00\x12\x46\n\x06Update\x12\".content.collections.UpdateRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x46\n\x06\x44\x65lete\x12\".content.collections.DeleteRequest\x1a\x16.google.protobuf.Empty\"\x00\x42:Z8github.com/perxteam/perxis/proto/collections;collectionsb\x06proto3'
   ,
-  dependencies=[google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,google_dot_protobuf_dot_wrappers__pb2.DESCRIPTOR,])
+  dependencies=[google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,])
 
 
 
@@ -96,9 +95,19 @@ _COLLECTION = _descriptor.Descriptor(
   syntax='proto3',
   extension_ranges=[],
   oneofs=[
-  ],
-  serialized_start=122,
-  serialized_end=242,
+    _descriptor.OneofDescriptor(
+      name='_single', full_name='content.collections.Collection._single',
+      index=0, containing_type=None,
+      create_key=_descriptor._internal_create_key,
+    fields=[]),
+    _descriptor.OneofDescriptor(
+      name='_system', full_name='content.collections.Collection._system',
+      index=1, containing_type=None,
+      create_key=_descriptor._internal_create_key,
+    fields=[]),
+  ],
+  serialized_start=91,
+  serialized_end=243,
 )
 
 
@@ -111,51 +120,9 @@ _CREATEREQUEST = _descriptor.Descriptor(
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='space_id', full_name='content.collections.CreateRequest.space_id', index=0,
-      number=1, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='env_id', full_name='content.collections.CreateRequest.env_id', index=1,
-      number=2, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='collection_id', full_name='content.collections.CreateRequest.collection_id', index=2,
-      number=3, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='name', full_name='content.collections.CreateRequest.name', index=3,
-      number=4, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='single', full_name='content.collections.CreateRequest.single', index=4,
-      number=5, type=8, cpp_type=7, label=1,
-      has_default_value=False, default_value=False,
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='system', full_name='content.collections.CreateRequest.system', index=5,
-      number=6, type=8, cpp_type=7, label=1,
-      has_default_value=False, default_value=False,
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='schema', full_name='content.collections.CreateRequest.schema', index=6,
-      number=7, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
+      name='coll', full_name='content.collections.CreateRequest.coll', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
@@ -172,7 +139,7 @@ _CREATEREQUEST = _descriptor.Descriptor(
   oneofs=[
   ],
   serialized_start=245,
-  serialized_end=379,
+  serialized_end=307,
 )
 
 
@@ -185,7 +152,7 @@ _CREATERESPONSE = _descriptor.Descriptor(
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='collection', full_name='content.collections.CreateResponse.collection', index=0,
+      name='created', full_name='content.collections.CreateResponse.created', index=0,
       number=1, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
@@ -203,8 +170,8 @@ _CREATERESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=381,
-  serialized_end=450,
+  serialized_start=309,
+  serialized_end=375,
 )
 
 
@@ -249,8 +216,8 @@ _GETREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=452,
-  serialized_end=521,
+  serialized_start=377,
+  serialized_end=446,
 )
 
 
@@ -281,8 +248,8 @@ _GETRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=523,
-  serialized_end=589,
+  serialized_start=448,
+  serialized_end=514,
 )
 
 
@@ -320,8 +287,8 @@ _LISTREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=591,
-  serialized_end=638,
+  serialized_start=516,
+  serialized_end=563,
 )
 
 
@@ -352,8 +319,8 @@ _LISTRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=640,
-  serialized_end=708,
+  serialized_start=565,
+  serialized_end=633,
 )
 
 
@@ -366,47 +333,12 @@ _UPDATEREQUEST = _descriptor.Descriptor(
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='space_id', full_name='content.collections.UpdateRequest.space_id', index=0,
-      number=1, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='env_id', full_name='content.collections.UpdateRequest.env_id', index=1,
-      number=2, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='collection_id', full_name='content.collections.UpdateRequest.collection_id', index=2,
-      number=3, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='name', full_name='content.collections.UpdateRequest.name', index=3,
-      number=4, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='single', full_name='content.collections.UpdateRequest.single', index=4,
-      number=5, type=11, cpp_type=10, label=1,
+      name='coll', full_name='content.collections.UpdateRequest.coll', index=0,
+      number=1, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='schema', full_name='content.collections.UpdateRequest.schema', index=5,
-      number=6, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
   ],
   extensions=[
   ],
@@ -419,8 +351,8 @@ _UPDATEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=711,
-  serialized_end=857,
+  serialized_start=635,
+  serialized_end=697,
 )
 
 
@@ -465,14 +397,21 @@ _DELETEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=859,
-  serialized_end=931,
+  serialized_start=699,
+  serialized_end=771,
 )
 
-_CREATERESPONSE.fields_by_name['collection'].message_type = _COLLECTION
+_COLLECTION.oneofs_by_name['_single'].fields.append(
+  _COLLECTION.fields_by_name['single'])
+_COLLECTION.fields_by_name['single'].containing_oneof = _COLLECTION.oneofs_by_name['_single']
+_COLLECTION.oneofs_by_name['_system'].fields.append(
+  _COLLECTION.fields_by_name['system'])
+_COLLECTION.fields_by_name['system'].containing_oneof = _COLLECTION.oneofs_by_name['_system']
+_CREATEREQUEST.fields_by_name['coll'].message_type = _COLLECTION
+_CREATERESPONSE.fields_by_name['created'].message_type = _COLLECTION
 _GETRESPONSE.fields_by_name['collection'].message_type = _COLLECTION
 _LISTRESPONSE.fields_by_name['collections'].message_type = _COLLECTION
-_UPDATEREQUEST.fields_by_name['single'].message_type = google_dot_protobuf_dot_wrappers__pb2._BOOLVALUE
+_UPDATEREQUEST.fields_by_name['coll'].message_type = _COLLECTION
 DESCRIPTOR.message_types_by_name['Collection'] = _COLLECTION
 DESCRIPTOR.message_types_by_name['CreateRequest'] = _CREATEREQUEST
 DESCRIPTOR.message_types_by_name['CreateResponse'] = _CREATERESPONSE
@@ -557,8 +496,8 @@ _COLLECTIONS = _descriptor.ServiceDescriptor(
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=934,
-  serialized_end=1331,
+  serialized_start=774,
+  serialized_end=1171,
   methods=[
   _descriptor.MethodDescriptor(
     name='Create',
diff --git a/perxis/common/common_pb2.py b/perxis/common/common_pb2.py
index c3ba47f99534bd9a81a8de09619f3bae5d5c85a7..4a239950822553cc5f22102ab3a892534e839917 100644
--- a/perxis/common/common_pb2.py
+++ b/perxis/common/common_pb2.py
@@ -23,7 +23,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=b'Z.github.com/perxteam/perxis/proto/common;common',
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\x13\x63ommon/common.proto\x12\x06\x63ommon\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1egoogle/protobuf/wrappers.proto\"\xb1\x01\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x12\n\nidentities\x18\x03 \x03(\t\x12\x14\n\x0c\x64isplay_name\x18\x04 \x01(\t\x12\r\n\x05\x65mail\x18\x05 \x01(\t\x12\x16\n\x0e\x65mail_verified\x18\x06 \x01(\x08\x12\x12\n\navatar_uri\x18\x07 \x01(\t\x12*\n\x06system\x18\n \x01(\x0b\x32\x1a.google.protobuf.BoolValue\"O\n\x0cOrganization\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12\x10\n\x08logo_uri\x18\x05 \x01(\t\"j\n\x16OrganizationMembership\x12\n\n\x02id\x18\x01 \x01(\t\x12\x17\n\x0forganization_id\x18\x02 \x01(\t\x12\x0f\n\x07user_id\x18\x03 \x01(\t\x12\x1a\n\x04role\x18\x04 \x01(\x0e\x32\x0c.common.Role\"\xac\x02\n\x0fSpaceInvitation\x12\n\n\x02id\x18\x01 \x01(\t\x12\r\n\x05\x65mail\x18\x02 \x01(\t\x12\x17\n\x0forganization_id\x18\x03 \x01(\t\x12\x10\n\x08space_id\x18\x04 \x01(\t\x12\x12\n\ncreated_by\x18\x05 \x01(\t\x12\x12\n\nspace_role\x18\x06 \x01(\t\x12\x0c\n\x04sent\x18\x07 \x01(\x08\x12\x0f\n\x07pending\x18\x08 \x01(\x08\x12.\n\ncreated_at\x18\t \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12+\n\x07sent_at\x18\n \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12/\n\x0bvalid_until\x18\x0b \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"n\n\x05Space\x12\n\n\x02id\x18\x01 \x01(\t\x12\x17\n\x0forganization_id\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x04 \x01(\t\x12\x0c\n\x04host\x18\x05 \x01(\t\x12\x0f\n\x07\x61pi_url\x18\x06 \x01(\t\"\xe4\x01\n\nCollection\x12\n\n\x02id\x18\x01 \x01(\t\x12\x10\n\x08space_id\x18\x02 \x01(\t\x12\x16\n\x0e\x65nvironment_id\x18\x03 \x01(\t\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\x0e\n\x06schema\x18\x05 \x01(\t\x12*\n\x06single\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12*\n\x06hidden\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12*\n\x06system\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\"\xf5\x03\n\x04Item\x12\n\n\x02id\x18\x01 \x01(\t\x12\x10\n\x08space_id\x18\x02 \x01(\t\x12\x16\n\x0e\x65nvironment_id\x18\x03 \x01(\t\x12\x15\n\rcollection_id\x18\x04 \x01(\t\x12\x0e\n\x06status\x18\x05 \x01(\t\x12.\n\ncreated_at\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x12\n\ncreated_by\x18\x07 \x01(\t\x12%\n\x04\x64\x61ta\x18\x08 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x34\n\x0ctranslations\x18\t \x03(\x0b\x32\x1e.common.Item.TranslationsEntry\x12\x13\n\x0brevision_id\x18\n \x01(\t\x12\x30\n\x0cpublished_at\x18\x0b \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x14\n\x0cpublished_by\x18\x0c \x01(\t\x12/\n\x0b\x61rchived_at\x18\r \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x13\n\x0b\x61rchived_by\x18\x0e \x01(\t\x1aL\n\x11TranslationsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.google.protobuf.Struct:\x02\x38\x01\"\xa7\x01\n\x10\x46indItemsOptions\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x16\n\x0e\x65nvironment_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x1f\n\x07\x66ilters\x18\x04 \x03(\x0b\x32\x0e.common.Filter\x12\x10\n\x08page_num\x18\x08 \x01(\x05\x12\x11\n\tpage_size\x18\t \x01(\x05\x12\x0c\n\x04sort\x18\n \x03(\t\"\xb5\x01\n\x0b\x45nvironment\x12\n\n\x02id\x18\x01 \x01(\t\x12\x10\n\x08space_id\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12(\n\x05state\x18\x04 \x01(\x0e\x32\x19.common.Environment.State\x12\x0f\n\x07\x61liases\x18\x05 \x03(\t\"8\n\x05State\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x0b\n\x07PENDING\x10\x01\x12\t\n\x05READY\x10\x02\x12\n\n\x06\x46\x41ILED\x10\x03\"4\n\x06Locale\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x10\n\x08space_id\x18\x03 \x01(\t\"x\n\tSpaceRole\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x10\n\x08space_id\x18\x03 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x05 \x01(\t\x12*\n\rcontent_rules\x18\x06 \x03(\x0b\x32\x13.common.ContentRule\"\xfd\x01\n\x0b\x43ontentRule\x12\n\n\x02id\x18\x01 \x01(\t\x12\x15\n\rcollection_id\x18\x02 \x01(\t\x12\"\n\x06\x63reate\x18\x05 \x01(\x0e\x32\x12.common.ItemAccess\x12 \n\x04read\x18\x06 \x01(\x0e\x32\x12.common.ItemAccess\x12\"\n\x06update\x18\x07 \x01(\x0e\x32\x12.common.ItemAccess\x12\"\n\x06\x64\x65lete\x18\x08 \x01(\x0e\x32\x12.common.ItemAccess\x12\x1d\n\x15\x66ields_read_blacklist\x18\n \x03(\t\x12\x1e\n\x16\x66ields_write_blacklist\x18\x0b \x03(\t\"J\n\x06\x46ilter\x12\n\n\x02op\x18\x01 \x01(\t\x12\r\n\x05\x66ield\x18\x02 \x01(\t\x12%\n\x05value\x18\x03 \x01(\x0b\x32\x16.google.protobuf.Value\"N\n\x04\x46ile\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0c\n\x04size\x18\x03 \x01(\x05\x12\x11\n\tmime_type\x18\x04 \x01(\t\x12\x0b\n\x03url\x18\x05 \x01(\t\"@\n\x0b\x46indOptions\x12\x0c\n\x04sort\x18\x01 \x03(\t\x12\x10\n\x08page_num\x18\x02 \x01(\x05\x12\x11\n\tpage_size\x18\x03 \x01(\x05*8\n\x04Role\x12\x0e\n\nNOT_MEMBER\x10\x00\x12\n\n\x06MEMBER\x10\x01\x12\t\n\x05OWNER\x10\x02\x12\t\n\x05\x41\x44MIN\x10\x03*3\n\nItemAccess\x12\x08\n\x04NONE\x10\x00\x12\x07\n\x03\x41NY\x10\x01\x12\x08\n\x04MINE\x10\x02\x12\x08\n\x04ROLE\x10\x03\x42\x30Z.github.com/perxteam/perxis/proto/common;commonb\x06proto3'
+  serialized_pb=b'\n\x13\x63ommon/common.proto\x12\x06\x63ommon\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1egoogle/protobuf/wrappers.proto\"\xb1\x01\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x12\n\nidentities\x18\x03 \x03(\t\x12\x14\n\x0c\x64isplay_name\x18\x04 \x01(\t\x12\r\n\x05\x65mail\x18\x05 \x01(\t\x12\x16\n\x0e\x65mail_verified\x18\x06 \x01(\x08\x12\x12\n\navatar_uri\x18\x07 \x01(\t\x12*\n\x06system\x18\n \x01(\x0b\x32\x1a.google.protobuf.BoolValue\"O\n\x0cOrganization\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12\x10\n\x08logo_uri\x18\x05 \x01(\t\"j\n\x16OrganizationMembership\x12\n\n\x02id\x18\x01 \x01(\t\x12\x17\n\x0forganization_id\x18\x02 \x01(\t\x12\x0f\n\x07user_id\x18\x03 \x01(\t\x12\x1a\n\x04role\x18\x04 \x01(\x0e\x32\x0c.common.Role\"\xac\x02\n\x0fSpaceInvitation\x12\n\n\x02id\x18\x01 \x01(\t\x12\r\n\x05\x65mail\x18\x02 \x01(\t\x12\x17\n\x0forganization_id\x18\x03 \x01(\t\x12\x10\n\x08space_id\x18\x04 \x01(\t\x12\x12\n\ncreated_by\x18\x05 \x01(\t\x12\x12\n\nspace_role\x18\x06 \x01(\t\x12\x0c\n\x04sent\x18\x07 \x01(\x08\x12\x0f\n\x07pending\x18\x08 \x01(\x08\x12.\n\ncreated_at\x18\t \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12+\n\x07sent_at\x18\n \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12/\n\x0bvalid_until\x18\x0b \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"n\n\x05Space\x12\n\n\x02id\x18\x01 \x01(\t\x12\x17\n\x0forganization_id\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x04 \x01(\t\x12\x0c\n\x04host\x18\x05 \x01(\t\x12\x0f\n\x07\x61pi_url\x18\x06 \x01(\t\"\xe4\x01\n\nCollection\x12\n\n\x02id\x18\x01 \x01(\t\x12\x10\n\x08space_id\x18\x02 \x01(\t\x12\x16\n\x0e\x65nvironment_id\x18\x03 \x01(\t\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\x0e\n\x06schema\x18\x05 \x01(\t\x12*\n\x06single\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12*\n\x06hidden\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12*\n\x06system\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\"\xf5\x03\n\x04Item\x12\n\n\x02id\x18\x01 \x01(\t\x12\x10\n\x08space_id\x18\x02 \x01(\t\x12\x16\n\x0e\x65nvironment_id\x18\x03 \x01(\t\x12\x15\n\rcollection_id\x18\x04 \x01(\t\x12\x0e\n\x06status\x18\x05 \x01(\t\x12.\n\ncreated_at\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x12\n\ncreated_by\x18\x07 \x01(\t\x12%\n\x04\x64\x61ta\x18\x08 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x34\n\x0ctranslations\x18\t \x03(\x0b\x32\x1e.common.Item.TranslationsEntry\x12\x13\n\x0brevision_id\x18\n \x01(\t\x12\x30\n\x0cpublished_at\x18\x0b \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x14\n\x0cpublished_by\x18\x0c \x01(\t\x12/\n\x0b\x61rchived_at\x18\r \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x13\n\x0b\x61rchived_by\x18\x0e \x01(\t\x1aL\n\x11TranslationsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.google.protobuf.Struct:\x02\x38\x01\"\xa7\x01\n\x10\x46indItemsOptions\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x16\n\x0e\x65nvironment_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x1f\n\x07\x66ilters\x18\x04 \x03(\x0b\x32\x0e.common.Filter\x12\x10\n\x08page_num\x18\x08 \x01(\x05\x12\x11\n\tpage_size\x18\t \x01(\x05\x12\x0c\n\x04sort\x18\n \x03(\t\"\xb5\x01\n\x0b\x45nvironment\x12\n\n\x02id\x18\x01 \x01(\t\x12\x10\n\x08space_id\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12(\n\x05state\x18\x04 \x01(\x0e\x32\x19.common.Environment.State\x12\x0f\n\x07\x61liases\x18\x05 \x03(\t\"8\n\x05State\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x0b\n\x07PENDING\x10\x01\x12\t\n\x05READY\x10\x02\x12\n\n\x06\x46\x41ILED\x10\x03\"4\n\x06Locale\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x10\n\x08space_id\x18\x03 \x01(\t\"x\n\tSpaceRole\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x10\n\x08space_id\x18\x03 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x05 \x01(\t\x12*\n\rcontent_rules\x18\x06 \x03(\x0b\x32\x13.common.ContentRule\"\xfd\x01\n\x0b\x43ontentRule\x12\n\n\x02id\x18\x01 \x01(\t\x12\x15\n\rcollection_id\x18\x02 \x01(\t\x12\"\n\x06\x63reate\x18\x05 \x01(\x0e\x32\x12.common.ItemAccess\x12 \n\x04read\x18\x06 \x01(\x0e\x32\x12.common.ItemAccess\x12\"\n\x06update\x18\x07 \x01(\x0e\x32\x12.common.ItemAccess\x12\"\n\x06\x64\x65lete\x18\x08 \x01(\x0e\x32\x12.common.ItemAccess\x12\x1d\n\x15\x66ields_read_blacklist\x18\n \x03(\t\x12\x1e\n\x16\x66ields_write_blacklist\x18\x0b \x03(\t\"J\n\x06\x46ilter\x12\n\n\x02op\x18\x01 \x01(\t\x12\r\n\x05\x66ield\x18\x02 \x01(\t\x12%\n\x05value\x18\x03 \x01(\x0b\x32\x16.google.protobuf.Value\"N\n\x04\x46ile\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0c\n\x04size\x18\x03 \x01(\x05\x12\x11\n\tmime_type\x18\x04 \x01(\t\x12\x0b\n\x03url\x18\x05 \x01(\t\"@\n\x0b\x46indOptions\x12\x0c\n\x04sort\x18\x01 \x03(\t\x12\x10\n\x08page_num\x18\x02 \x01(\x05\x12\x11\n\tpage_size\x18\x03 \x01(\x05\"\x92\x01\n\x04Rule\x12\n\n\x02id\x18\x01 \x01(\t\x12\x15\n\rcollection_id\x18\x02 \x01(\t\x12\x1f\n\x07\x61\x63tions\x18\x03 \x03(\x0e\x32\x0e.common.Action\x12\x1e\n\x06\x61\x63\x63\x65ss\x18\x04 \x01(\x0e\x32\x0e.common.Access\x12\x0e\n\x06\x66ields\x18\x06 \x03(\t\x12\x16\n\x0e\x66ields_allowed\x18\x07 \x01(\x08\"?\n\x0c\x43ollaborator\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0f\n\x07user_id\x18\x02 \x01(\t\x12\x0c\n\x04role\x18\x03 \x01(\t*8\n\x04Role\x12\x0e\n\nNOT_MEMBER\x10\x00\x12\n\n\x06MEMBER\x10\x01\x12\t\n\x05OWNER\x10\x02\x12\t\n\x05\x41\x44MIN\x10\x03*\x16\n\nItemAccess\x12\x08\n\x04NONE\x10\x00*%\n\x06\x41\x63\x63\x65ss\x12\x07\n\x03\x41NY\x10\x00\x12\x08\n\x04MINE\x10\x01\x12\x08\n\x04ROLE\x10\x02*C\n\x06\x41\x63tion\x12\x0b\n\x07UNKNOWN\x10\x00\x12\n\n\x06\x43REATE\x10\x01\x12\x08\n\x04READ\x10\x02\x12\n\n\x06UPDATE\x10\x03\x12\n\n\x06\x44\x45LETE\x10\x04\x42\x30Z.github.com/perxteam/perxis/proto/common;commonb\x06proto3'
   ,
   dependencies=[google_dot_protobuf_dot_timestamp__pb2.DESCRIPTOR,google_dot_protobuf_dot_struct__pb2.DESCRIPTOR,google_dot_protobuf_dot_wrappers__pb2.DESCRIPTOR,])
 
@@ -57,8 +57,8 @@ _ROLE = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=2653,
-  serialized_end=2709,
+  serialized_start=2867,
+  serialized_end=2923,
 )
 _sym_db.RegisterEnumDescriptor(_ROLE)
 
@@ -75,38 +75,100 @@ _ITEMACCESS = _descriptor.EnumDescriptor(
       serialized_options=None,
       type=None,
       create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=2925,
+  serialized_end=2947,
+)
+_sym_db.RegisterEnumDescriptor(_ITEMACCESS)
+
+ItemAccess = enum_type_wrapper.EnumTypeWrapper(_ITEMACCESS)
+_ACCESS = _descriptor.EnumDescriptor(
+  name='Access',
+  full_name='common.Access',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
     _descriptor.EnumValueDescriptor(
-      name='ANY', index=1, number=1,
+      name='ANY', index=0, number=0,
       serialized_options=None,
       type=None,
       create_key=_descriptor._internal_create_key),
     _descriptor.EnumValueDescriptor(
-      name='MINE', index=2, number=2,
+      name='MINE', index=1, number=1,
       serialized_options=None,
       type=None,
       create_key=_descriptor._internal_create_key),
     _descriptor.EnumValueDescriptor(
-      name='ROLE', index=3, number=3,
+      name='ROLE', index=2, number=2,
       serialized_options=None,
       type=None,
       create_key=_descriptor._internal_create_key),
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=2711,
-  serialized_end=2762,
+  serialized_start=2949,
+  serialized_end=2986,
 )
-_sym_db.RegisterEnumDescriptor(_ITEMACCESS)
+_sym_db.RegisterEnumDescriptor(_ACCESS)
 
-ItemAccess = enum_type_wrapper.EnumTypeWrapper(_ITEMACCESS)
+Access = enum_type_wrapper.EnumTypeWrapper(_ACCESS)
+_ACTION = _descriptor.EnumDescriptor(
+  name='Action',
+  full_name='common.Action',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='UNKNOWN', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='CREATE', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='READ', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='UPDATE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DELETE', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=2988,
+  serialized_end=3055,
+)
+_sym_db.RegisterEnumDescriptor(_ACTION)
+
+Action = enum_type_wrapper.EnumTypeWrapper(_ACTION)
 NOT_MEMBER = 0
 MEMBER = 1
 OWNER = 2
 ADMIN = 3
 NONE = 0
-ANY = 1
-MINE = 2
-ROLE = 3
+ANY = 0
+MINE = 1
+ROLE = 2
+UNKNOWN = 0
+CREATE = 1
+READ = 2
+UPDATE = 3
+DELETE = 4
 
 
 _ENVIRONMENT_STATE = _descriptor.EnumDescriptor(
@@ -1216,6 +1278,119 @@ _FINDOPTIONS = _descriptor.Descriptor(
   serialized_end=2651,
 )
 
+
+_RULE = _descriptor.Descriptor(
+  name='Rule',
+  full_name='common.Rule',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='id', full_name='common.Rule.id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='collection_id', full_name='common.Rule.collection_id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='actions', full_name='common.Rule.actions', index=2,
+      number=3, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='access', full_name='common.Rule.access', index=3,
+      number=4, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='fields', full_name='common.Rule.fields', index=4,
+      number=6, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='fields_allowed', full_name='common.Rule.fields_allowed', index=5,
+      number=7, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2654,
+  serialized_end=2800,
+)
+
+
+_COLLABORATOR = _descriptor.Descriptor(
+  name='Collaborator',
+  full_name='common.Collaborator',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='space_id', full_name='common.Collaborator.space_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='user_id', full_name='common.Collaborator.user_id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='role', full_name='common.Collaborator.role', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2802,
+  serialized_end=2865,
+)
+
 _USER.fields_by_name['system'].message_type = google_dot_protobuf_dot_wrappers__pb2._BOOLVALUE
 _ORGANIZATIONMEMBERSHIP.fields_by_name['role'].enum_type = _ROLE
 _SPACEINVITATION.fields_by_name['created_at'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP
@@ -1240,6 +1415,8 @@ _CONTENTRULE.fields_by_name['read'].enum_type = _ITEMACCESS
 _CONTENTRULE.fields_by_name['update'].enum_type = _ITEMACCESS
 _CONTENTRULE.fields_by_name['delete'].enum_type = _ITEMACCESS
 _FILTER.fields_by_name['value'].message_type = google_dot_protobuf_dot_struct__pb2._VALUE
+_RULE.fields_by_name['actions'].enum_type = _ACTION
+_RULE.fields_by_name['access'].enum_type = _ACCESS
 DESCRIPTOR.message_types_by_name['User'] = _USER
 DESCRIPTOR.message_types_by_name['Organization'] = _ORGANIZATION
 DESCRIPTOR.message_types_by_name['OrganizationMembership'] = _ORGANIZATIONMEMBERSHIP
@@ -1255,8 +1432,12 @@ DESCRIPTOR.message_types_by_name['ContentRule'] = _CONTENTRULE
 DESCRIPTOR.message_types_by_name['Filter'] = _FILTER
 DESCRIPTOR.message_types_by_name['File'] = _FILE
 DESCRIPTOR.message_types_by_name['FindOptions'] = _FINDOPTIONS
+DESCRIPTOR.message_types_by_name['Rule'] = _RULE
+DESCRIPTOR.message_types_by_name['Collaborator'] = _COLLABORATOR
 DESCRIPTOR.enum_types_by_name['Role'] = _ROLE
 DESCRIPTOR.enum_types_by_name['ItemAccess'] = _ITEMACCESS
+DESCRIPTOR.enum_types_by_name['Access'] = _ACCESS
+DESCRIPTOR.enum_types_by_name['Action'] = _ACTION
 _sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
 User = _reflection.GeneratedProtocolMessageType('User', (_message.Message,), {
@@ -1372,6 +1553,20 @@ FindOptions = _reflection.GeneratedProtocolMessageType('FindOptions', (_message.
   })
 _sym_db.RegisterMessage(FindOptions)
 
+Rule = _reflection.GeneratedProtocolMessageType('Rule', (_message.Message,), {
+  'DESCRIPTOR' : _RULE,
+  '__module__' : 'common.common_pb2'
+  # @@protoc_insertion_point(class_scope:common.Rule)
+  })
+_sym_db.RegisterMessage(Rule)
+
+Collaborator = _reflection.GeneratedProtocolMessageType('Collaborator', (_message.Message,), {
+  'DESCRIPTOR' : _COLLABORATOR,
+  '__module__' : 'common.common_pb2'
+  # @@protoc_insertion_point(class_scope:common.Collaborator)
+  })
+_sym_db.RegisterMessage(Collaborator)
+
 
 DESCRIPTOR._options = None
 _ITEM_TRANSLATIONSENTRY._options = None
diff --git a/perxis/environments/environments_pb2.py b/perxis/environments/environments_pb2.py
index 9992fc917b2d0687e4cf94c5269ed5eec982b863..7aefe1dfac61e30e6100bd5fe46136bdc83d6245 100644
--- a/perxis/environments/environments_pb2.py
+++ b/perxis/environments/environments_pb2.py
@@ -20,7 +20,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=b'Z:github.com/perxteam/perxis/proto/environments;environments',
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\x1f\x65nvironments/environments.proto\x12\x14\x63ontent.environments\x1a\x1bgoogle/protobuf/empty.proto\"\xb3\x01\n\x0b\x45nvironment\x12\n\n\x02id\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x36\n\x05state\x18\x03 \x01(\x0e\x32\'.content.environments.Environment.State\x12\x0f\n\x07\x61liases\x18\x05 \x03(\t\":\n\x05State\x12\x0b\n\x07UNKNOWN\x10\x00\x12\r\n\tPREPARING\x10\x01\x12\t\n\x05READY\x10\x02\x12\n\n\x06\x46\x41ILED\x10\x03\"W\n\rCreateRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0f\n\x07\x62\x61se_id\x18\x02 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x03 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x04 \x01(\t\"@\n\x0e\x43reateResponse\x12.\n\x03\x65nv\x18\x01 \x01(\x0b\x32!.content.environments.Environment\"\x1f\n\x0bListRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\"?\n\x0cListResponse\x12/\n\x04\x65nvs\x18\x01 \x03(\x0b\x32!.content.environments.Environment\".\n\nGetRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\"=\n\x0bGetResponse\x12.\n\x03\x65nv\x18\x01 \x01(\x0b\x32!.content.environments.Environment\"F\n\rUpdateRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\"B\n\x0fSetAliasRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\r\n\x05\x61lias\x18\x03 \x01(\t\"E\n\x12RemoveAliasRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\r\n\x05\x61lias\x18\x03 \x01(\t\"1\n\rDeleteRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t2\xb6\x04\n\x0c\x45nvironments\x12U\n\x06\x43reate\x12#.content.environments.CreateRequest\x1a$.content.environments.CreateResponse\"\x00\x12L\n\x03Get\x12 .content.environments.GetRequest\x1a!.content.environments.GetResponse\"\x00\x12O\n\x04List\x12!.content.environments.ListRequest\x1a\".content.environments.ListResponse\"\x00\x12G\n\x06Update\x12#.content.environments.UpdateRequest\x1a\x16.google.protobuf.Empty\"\x00\x12K\n\x08SetAlias\x12%.content.environments.SetAliasRequest\x1a\x16.google.protobuf.Empty\"\x00\x12Q\n\x0bRemoveAlias\x12(.content.environments.RemoveAliasRequest\x1a\x16.google.protobuf.Empty\"\x00\x12G\n\x06\x44\x65lete\x12#.content.environments.DeleteRequest\x1a\x16.google.protobuf.Empty\"\x00\x42<Z:github.com/perxteam/perxis/proto/environments;environmentsb\x06proto3'
+  serialized_pb=b'\n\x1f\x65nvironments/environments.proto\x12\x14\x63ontent.environments\x1a\x1bgoogle/protobuf/empty.proto\"\x8f\x02\n\x0b\x45nvironment\x12\n\n\x02id\x18\x01 \x01(\t\x12\x10\n\x08space_id\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12\x36\n\x05state\x18\x04 \x01(\x0e\x32\'.content.environments.Environment.State\x12\x12\n\nstate_info\x18\x05 \x01(\t\x12\x0f\n\x07\x61liases\x18\x06 \x03(\t\x12,\n\x06\x63onfig\x18\n \x01(\x0b\x32\x1c.content.environments.Config\"B\n\x05State\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x07\n\x03NEW\x10\x01\x12\r\n\tPREPARING\x10\x02\x12\t\n\x05READY\x10\x03\x12\t\n\x05\x45RROR\x10\x04\"-\n\x06\x43onfig\x12\x11\n\tsource_id\x18\x01 \x01(\t\x12\x10\n\x08\x66\x65\x61tures\x18\x02 \x03(\t\"?\n\rCreateRequest\x12.\n\x03\x65nv\x18\x01 \x01(\x0b\x32!.content.environments.Environment\"D\n\x0e\x43reateResponse\x12\x32\n\x07\x63reated\x18\x01 \x01(\x0b\x32!.content.environments.Environment\"\x1f\n\x0bListRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\"?\n\x0cListResponse\x12/\n\x04\x65nvs\x18\x01 \x03(\x0b\x32!.content.environments.Environment\".\n\nGetRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\"=\n\x0bGetResponse\x12.\n\x03\x65nv\x18\x01 \x01(\x0b\x32!.content.environments.Environment\"?\n\rUpdateRequest\x12.\n\x03\x65nv\x18\x01 \x01(\x0b\x32!.content.environments.Environment\"B\n\x0fSetAliasRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\r\n\x05\x61lias\x18\x03 \x01(\t\"E\n\x12RemoveAliasRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\r\n\x05\x61lias\x18\x03 \x01(\t\"1\n\rDeleteRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t2\xb6\x04\n\x0c\x45nvironments\x12U\n\x06\x43reate\x12#.content.environments.CreateRequest\x1a$.content.environments.CreateResponse\"\x00\x12L\n\x03Get\x12 .content.environments.GetRequest\x1a!.content.environments.GetResponse\"\x00\x12O\n\x04List\x12!.content.environments.ListRequest\x1a\".content.environments.ListResponse\"\x00\x12G\n\x06Update\x12#.content.environments.UpdateRequest\x1a\x16.google.protobuf.Empty\"\x00\x12K\n\x08SetAlias\x12%.content.environments.SetAliasRequest\x1a\x16.google.protobuf.Empty\"\x00\x12Q\n\x0bRemoveAlias\x12(.content.environments.RemoveAliasRequest\x1a\x16.google.protobuf.Empty\"\x00\x12G\n\x06\x44\x65lete\x12#.content.environments.DeleteRequest\x1a\x16.google.protobuf.Empty\"\x00\x42<Z:github.com/perxteam/perxis/proto/environments;environmentsb\x06proto3'
   ,
   dependencies=[google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,])
 
@@ -39,25 +39,30 @@ _ENVIRONMENT_STATE = _descriptor.EnumDescriptor(
       type=None,
       create_key=_descriptor._internal_create_key),
     _descriptor.EnumValueDescriptor(
-      name='PREPARING', index=1, number=1,
+      name='NEW', index=1, number=1,
       serialized_options=None,
       type=None,
       create_key=_descriptor._internal_create_key),
     _descriptor.EnumValueDescriptor(
-      name='READY', index=2, number=2,
+      name='PREPARING', index=2, number=2,
       serialized_options=None,
       type=None,
       create_key=_descriptor._internal_create_key),
     _descriptor.EnumValueDescriptor(
-      name='FAILED', index=3, number=3,
+      name='READY', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='ERROR', index=4, number=4,
       serialized_options=None,
       type=None,
       create_key=_descriptor._internal_create_key),
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=208,
-  serialized_end=266,
+  serialized_start=292,
+  serialized_end=358,
 )
 _sym_db.RegisterEnumDescriptor(_ENVIRONMENT_STATE)
 
@@ -78,26 +83,47 @@ _ENVIRONMENT = _descriptor.Descriptor(
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='description', full_name='content.environments.Environment.description', index=1,
+      name='space_id', full_name='content.environments.Environment.space_id', index=1,
       number=2, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='state', full_name='content.environments.Environment.state', index=2,
-      number=3, type=14, cpp_type=8, label=1,
+      name='description', full_name='content.environments.Environment.description', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='state', full_name='content.environments.Environment.state', index=3,
+      number=4, type=14, cpp_type=8, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='aliases', full_name='content.environments.Environment.aliases', index=3,
-      number=5, type=9, cpp_type=9, label=3,
+      name='state_info', full_name='content.environments.Environment.state_info', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='aliases', full_name='content.environments.Environment.aliases', index=5,
+      number=6, type=9, cpp_type=9, label=3,
       has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='config', full_name='content.environments.Environment.config', index=6,
+      number=10, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
   ],
   extensions=[
   ],
@@ -112,43 +138,61 @@ _ENVIRONMENT = _descriptor.Descriptor(
   oneofs=[
   ],
   serialized_start=87,
-  serialized_end=266,
+  serialized_end=358,
 )
 
 
-_CREATEREQUEST = _descriptor.Descriptor(
-  name='CreateRequest',
-  full_name='content.environments.CreateRequest',
+_CONFIG = _descriptor.Descriptor(
+  name='Config',
+  full_name='content.environments.Config',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='space_id', full_name='content.environments.CreateRequest.space_id', index=0,
+      name='source_id', full_name='content.environments.Config.source_id', index=0,
       number=1, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='base_id', full_name='content.environments.CreateRequest.base_id', index=1,
-      number=2, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='env_id', full_name='content.environments.CreateRequest.env_id', index=2,
-      number=3, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
+      name='features', full_name='content.environments.Config.features', index=1,
+      number=2, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=360,
+  serialized_end=405,
+)
+
+
+_CREATEREQUEST = _descriptor.Descriptor(
+  name='CreateRequest',
+  full_name='content.environments.CreateRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
     _descriptor.FieldDescriptor(
-      name='description', full_name='content.environments.CreateRequest.description', index=3,
-      number=4, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
+      name='env', full_name='content.environments.CreateRequest.env', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
@@ -164,8 +208,8 @@ _CREATEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=268,
-  serialized_end=355,
+  serialized_start=407,
+  serialized_end=470,
 )
 
 
@@ -178,7 +222,7 @@ _CREATERESPONSE = _descriptor.Descriptor(
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='env', full_name='content.environments.CreateResponse.env', index=0,
+      name='created', full_name='content.environments.CreateResponse.created', index=0,
       number=1, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
@@ -196,8 +240,8 @@ _CREATERESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=357,
-  serialized_end=421,
+  serialized_start=472,
+  serialized_end=540,
 )
 
 
@@ -228,8 +272,8 @@ _LISTREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=423,
-  serialized_end=454,
+  serialized_start=542,
+  serialized_end=573,
 )
 
 
@@ -260,8 +304,8 @@ _LISTRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=456,
-  serialized_end=519,
+  serialized_start=575,
+  serialized_end=638,
 )
 
 
@@ -299,8 +343,8 @@ _GETREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=521,
-  serialized_end=567,
+  serialized_start=640,
+  serialized_end=686,
 )
 
 
@@ -331,8 +375,8 @@ _GETRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=569,
-  serialized_end=630,
+  serialized_start=688,
+  serialized_end=749,
 )
 
 
@@ -345,23 +389,9 @@ _UPDATEREQUEST = _descriptor.Descriptor(
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='space_id', full_name='content.environments.UpdateRequest.space_id', index=0,
-      number=1, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='env_id', full_name='content.environments.UpdateRequest.env_id', index=1,
-      number=2, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='description', full_name='content.environments.UpdateRequest.description', index=2,
-      number=3, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
+      name='env', full_name='content.environments.UpdateRequest.env', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
@@ -377,8 +407,8 @@ _UPDATEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=632,
-  serialized_end=702,
+  serialized_start=751,
+  serialized_end=814,
 )
 
 
@@ -423,8 +453,8 @@ _SETALIASREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=704,
-  serialized_end=770,
+  serialized_start=816,
+  serialized_end=882,
 )
 
 
@@ -469,8 +499,8 @@ _REMOVEALIASREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=772,
-  serialized_end=841,
+  serialized_start=884,
+  serialized_end=953,
 )
 
 
@@ -508,16 +538,20 @@ _DELETEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=843,
-  serialized_end=892,
+  serialized_start=955,
+  serialized_end=1004,
 )
 
 _ENVIRONMENT.fields_by_name['state'].enum_type = _ENVIRONMENT_STATE
+_ENVIRONMENT.fields_by_name['config'].message_type = _CONFIG
 _ENVIRONMENT_STATE.containing_type = _ENVIRONMENT
-_CREATERESPONSE.fields_by_name['env'].message_type = _ENVIRONMENT
+_CREATEREQUEST.fields_by_name['env'].message_type = _ENVIRONMENT
+_CREATERESPONSE.fields_by_name['created'].message_type = _ENVIRONMENT
 _LISTRESPONSE.fields_by_name['envs'].message_type = _ENVIRONMENT
 _GETRESPONSE.fields_by_name['env'].message_type = _ENVIRONMENT
+_UPDATEREQUEST.fields_by_name['env'].message_type = _ENVIRONMENT
 DESCRIPTOR.message_types_by_name['Environment'] = _ENVIRONMENT
+DESCRIPTOR.message_types_by_name['Config'] = _CONFIG
 DESCRIPTOR.message_types_by_name['CreateRequest'] = _CREATEREQUEST
 DESCRIPTOR.message_types_by_name['CreateResponse'] = _CREATERESPONSE
 DESCRIPTOR.message_types_by_name['ListRequest'] = _LISTREQUEST
@@ -537,6 +571,13 @@ Environment = _reflection.GeneratedProtocolMessageType('Environment', (_message.
   })
 _sym_db.RegisterMessage(Environment)
 
+Config = _reflection.GeneratedProtocolMessageType('Config', (_message.Message,), {
+  'DESCRIPTOR' : _CONFIG,
+  '__module__' : 'environments.environments_pb2'
+  # @@protoc_insertion_point(class_scope:content.environments.Config)
+  })
+_sym_db.RegisterMessage(Config)
+
 CreateRequest = _reflection.GeneratedProtocolMessageType('CreateRequest', (_message.Message,), {
   'DESCRIPTOR' : _CREATEREQUEST,
   '__module__' : 'environments.environments_pb2'
@@ -617,8 +658,8 @@ _ENVIRONMENTS = _descriptor.ServiceDescriptor(
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=895,
-  serialized_end=1461,
+  serialized_start=1007,
+  serialized_end=1573,
   methods=[
   _descriptor.MethodDescriptor(
     name='Create',
diff --git a/perxis/invitations/invitations_pb2.py b/perxis/invitations/invitations_pb2.py
index f7e4e0bdecb1490fa48a68714f09179276c9c3dd..3e18f5da1bd1ec6381c86ef799429e445fd736f9 100644
--- a/perxis/invitations/invitations_pb2.py
+++ b/perxis/invitations/invitations_pb2.py
@@ -22,7 +22,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=b'Z8github.com/perxteam/perxis/proto/invitations;invitations',
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\x1dinvitations/invitations.proto\x12\x13\x63ontent.invitations\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1egoogle/protobuf/wrappers.proto\"\xd3\x01\n\nInvitation\x12\n\n\x02id\x18\x01 \x01(\t\x12\r\n\x05\x65mail\x18\x02 \x01(\t\x12\x17\n\x0forganization_id\x18\x03 \x01(\t\x12\x10\n\x08space_id\x18\x04 \x01(\t\x12\x10\n\x08owner_id\x18\x05 \x01(\t\x12\x0c\n\x04role\x18\x06 \x01(\t\x12.\n\ncreated_at\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12/\n\x0bvalid_until\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"n\n\x06\x46ilter\x12\n\n\x02id\x18\x01 \x03(\t\x12\r\n\x05\x65mail\x18\x02 \x03(\t\x12\x17\n\x0forganization_id\x18\x03 \x03(\t\x12\x10\n\x08space_id\x18\x04 \x03(\t\x12\x10\n\x08owner_id\x18\x05 \x03(\t\x12\x0c\n\x04role\x18\x06 \x03(\t\"@\n\x0b\x46indOptions\x12\x0c\n\x04sort\x18\x01 \x03(\t\x12\x10\n\x08page_num\x18\x02 \x01(\x05\x12\x11\n\tpage_size\x18\x03 \x01(\x05\"\x81\x01\n\rCreateRequest\x12\r\n\x05\x65mail\x18\x01 \x01(\t\x12\x10\n\x08space_id\x18\x02 \x01(\t\x12\x0c\n\x04role\x18\x03 \x01(\t\x12\x10\n\x08owner_id\x18\x04 \x01(\t\x12/\n\x0bvalid_until\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"E\n\x0e\x43reateResponse\x12\x33\n\ninvitation\x18\x01 \x01(\x0b\x32\x1f.content.invitations.Invitation\"#\n\nGetRequest\x12\x15\n\rinvitation_id\x18\x01 \x01(\t\"B\n\x0bGetResponse\x12\x33\n\ninvitation\x18\x01 \x01(\x0b\x32\x1f.content.invitations.Invitation\"\xdb\x01\n\rUpdateRequest\x12\x15\n\rinvitation_id\x18\x01 \x01(\t\x12(\n\x04sent\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12+\n\x07pending\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12+\n\x07sent_at\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12/\n\x0bvalid_until\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\x1a\n\x18UpdateInvitationResponse\"7\n\rAcceptRequest\x12\x15\n\rinvitation_id\x18\x01 \x01(\t\x12\x0f\n\x07user_id\x18\x02 \x01(\t\"\x1a\n\x18\x41\x63\x63\x65ptInvitationResponse\"j\n\x0b\x46indRequest\x12+\n\x06\x66ilter\x18\x01 \x01(\x0b\x32\x1b.content.invitations.Filter\x12.\n\x04opts\x18\x02 \x01(\x0b\x32 .content.invitations.FindOptions\"S\n\x0c\x46indResponse\x12\x34\n\x0binvitations\x18\x01 \x03(\x0b\x32\x1f.content.invitations.Invitation\x12\r\n\x05total\x18\x02 \x01(\x03\"&\n\rDeleteRequest\x12\x15\n\rinvitation_id\x18\x01 \x01(\t\"\x1f\n\x1d\x44\x65leteSpaceInvitationResponse2\x8d\x03\n\x0bInvitations\x12S\n\x06\x43reate\x12\".content.invitations.CreateRequest\x1a#.content.invitations.CreateResponse\"\x00\x12J\n\x03Get\x12\x1f.content.invitations.GetRequest\x1a .content.invitations.GetResponse\"\x00\x12\x46\n\x06\x41\x63\x63\x65pt\x12\".content.invitations.AcceptRequest\x1a\x16.google.protobuf.Empty\"\x00\x12M\n\x04\x46ind\x12 .content.invitations.FindRequest\x1a!.content.invitations.FindResponse\"\x00\x12\x46\n\x06\x44\x65lete\x12\".content.invitations.DeleteRequest\x1a\x16.google.protobuf.Empty\"\x00\x42:Z8github.com/perxteam/perxis/proto/invitations;invitationsb\x06proto3'
+  serialized_pb=b'\n\x1dinvitations/invitations.proto\x12\x13\x63ontent.invitations\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1egoogle/protobuf/wrappers.proto\"\xca\x01\n\nInvitation\x12\n\n\x02id\x18\x01 \x01(\t\x12\r\n\x05\x65mail\x18\x02 \x01(\t\x12\x0e\n\x06org_id\x18\x03 \x01(\t\x12\x10\n\x08space_id\x18\x04 \x01(\t\x12\x10\n\x08owner_id\x18\x05 \x01(\t\x12\x0c\n\x04role\x18\x06 \x01(\t\x12.\n\ncreated_at\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12/\n\x0bvalid_until\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"e\n\x06\x46ilter\x12\n\n\x02id\x18\x01 \x03(\t\x12\r\n\x05\x65mail\x18\x02 \x03(\t\x12\x0e\n\x06org_id\x18\x03 \x03(\t\x12\x10\n\x08space_id\x18\x04 \x03(\t\x12\x10\n\x08owner_id\x18\x05 \x03(\t\x12\x0c\n\x04role\x18\x06 \x03(\t\"@\n\x0b\x46indOptions\x12\x0c\n\x04sort\x18\x01 \x03(\t\x12\x10\n\x08page_num\x18\x02 \x01(\x05\x12\x11\n\tpage_size\x18\x03 \x01(\x05\"D\n\rCreateRequest\x12\x33\n\ninvitation\x18\x01 \x01(\x0b\x32\x1f.content.invitations.Invitation\"E\n\x0e\x43reateResponse\x12\x33\n\ninvitation\x18\x01 \x01(\x0b\x32\x1f.content.invitations.Invitation\"#\n\nGetRequest\x12\x15\n\rinvitation_id\x18\x01 \x01(\t\"B\n\x0bGetResponse\x12\x33\n\ninvitation\x18\x01 \x01(\x0b\x32\x1f.content.invitations.Invitation\"\xdb\x01\n\rUpdateRequest\x12\x15\n\rinvitation_id\x18\x01 \x01(\t\x12(\n\x04sent\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12+\n\x07pending\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12+\n\x07sent_at\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12/\n\x0bvalid_until\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\x1a\n\x18UpdateInvitationResponse\"7\n\rAcceptRequest\x12\x15\n\rinvitation_id\x18\x01 \x01(\t\x12\x0f\n\x07user_id\x18\x02 \x01(\t\"\x1a\n\x18\x41\x63\x63\x65ptInvitationResponse\"j\n\x0b\x46indRequest\x12+\n\x06\x66ilter\x18\x01 \x01(\x0b\x32\x1b.content.invitations.Filter\x12.\n\x04opts\x18\x02 \x01(\x0b\x32 .content.invitations.FindOptions\"S\n\x0c\x46indResponse\x12\x34\n\x0binvitations\x18\x01 \x03(\x0b\x32\x1f.content.invitations.Invitation\x12\r\n\x05total\x18\x02 \x01(\x03\"&\n\rDeleteRequest\x12\x15\n\rinvitation_id\x18\x01 \x01(\t\"\x1f\n\x1d\x44\x65leteSpaceInvitationResponse2\x8d\x03\n\x0bInvitations\x12S\n\x06\x43reate\x12\".content.invitations.CreateRequest\x1a#.content.invitations.CreateResponse\"\x00\x12J\n\x03Get\x12\x1f.content.invitations.GetRequest\x1a .content.invitations.GetResponse\"\x00\x12\x46\n\x06\x41\x63\x63\x65pt\x12\".content.invitations.AcceptRequest\x1a\x16.google.protobuf.Empty\"\x00\x12M\n\x04\x46ind\x12 .content.invitations.FindRequest\x1a!.content.invitations.FindResponse\"\x00\x12\x46\n\x06\x44\x65lete\x12\".content.invitations.DeleteRequest\x1a\x16.google.protobuf.Empty\"\x00\x42:Z8github.com/perxteam/perxis/proto/invitations;invitationsb\x06proto3'
   ,
   dependencies=[google_dot_protobuf_dot_timestamp__pb2.DESCRIPTOR,google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,google_dot_protobuf_dot_wrappers__pb2.DESCRIPTOR,])
 
@@ -52,7 +52,7 @@ _INVITATION = _descriptor.Descriptor(
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='organization_id', full_name='content.invitations.Invitation.organization_id', index=2,
+      name='org_id', full_name='content.invitations.Invitation.org_id', index=2,
       number=3, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
@@ -106,7 +106,7 @@ _INVITATION = _descriptor.Descriptor(
   oneofs=[
   ],
   serialized_start=149,
-  serialized_end=360,
+  serialized_end=351,
 )
 
 
@@ -133,7 +133,7 @@ _FILTER = _descriptor.Descriptor(
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='organization_id', full_name='content.invitations.Filter.organization_id', index=2,
+      name='org_id', full_name='content.invitations.Filter.org_id', index=2,
       number=3, type=9, cpp_type=9, label=3,
       has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
@@ -172,8 +172,8 @@ _FILTER = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=362,
-  serialized_end=472,
+  serialized_start=353,
+  serialized_end=454,
 )
 
 
@@ -218,8 +218,8 @@ _FINDOPTIONS = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=474,
-  serialized_end=538,
+  serialized_start=456,
+  serialized_end=520,
 )
 
 
@@ -232,36 +232,8 @@ _CREATEREQUEST = _descriptor.Descriptor(
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='email', full_name='content.invitations.CreateRequest.email', index=0,
-      number=1, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='space_id', full_name='content.invitations.CreateRequest.space_id', index=1,
-      number=2, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='role', full_name='content.invitations.CreateRequest.role', index=2,
-      number=3, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='owner_id', full_name='content.invitations.CreateRequest.owner_id', index=3,
-      number=4, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='valid_until', full_name='content.invitations.CreateRequest.valid_until', index=4,
-      number=5, type=11, cpp_type=10, label=1,
+      name='invitation', full_name='content.invitations.CreateRequest.invitation', index=0,
+      number=1, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
@@ -278,8 +250,8 @@ _CREATEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=541,
-  serialized_end=670,
+  serialized_start=522,
+  serialized_end=590,
 )
 
 
@@ -310,8 +282,8 @@ _CREATERESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=672,
-  serialized_end=741,
+  serialized_start=592,
+  serialized_end=661,
 )
 
 
@@ -342,8 +314,8 @@ _GETREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=743,
-  serialized_end=778,
+  serialized_start=663,
+  serialized_end=698,
 )
 
 
@@ -374,8 +346,8 @@ _GETRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=780,
-  serialized_end=846,
+  serialized_start=700,
+  serialized_end=766,
 )
 
 
@@ -434,8 +406,8 @@ _UPDATEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=849,
-  serialized_end=1068,
+  serialized_start=769,
+  serialized_end=988,
 )
 
 
@@ -459,8 +431,8 @@ _UPDATEINVITATIONRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1070,
-  serialized_end=1096,
+  serialized_start=990,
+  serialized_end=1016,
 )
 
 
@@ -498,8 +470,8 @@ _ACCEPTREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1098,
-  serialized_end=1153,
+  serialized_start=1018,
+  serialized_end=1073,
 )
 
 
@@ -523,8 +495,8 @@ _ACCEPTINVITATIONRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1155,
-  serialized_end=1181,
+  serialized_start=1075,
+  serialized_end=1101,
 )
 
 
@@ -562,8 +534,8 @@ _FINDREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1183,
-  serialized_end=1289,
+  serialized_start=1103,
+  serialized_end=1209,
 )
 
 
@@ -601,8 +573,8 @@ _FINDRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1291,
-  serialized_end=1374,
+  serialized_start=1211,
+  serialized_end=1294,
 )
 
 
@@ -633,8 +605,8 @@ _DELETEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1376,
-  serialized_end=1414,
+  serialized_start=1296,
+  serialized_end=1334,
 )
 
 
@@ -658,13 +630,13 @@ _DELETESPACEINVITATIONRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1416,
-  serialized_end=1447,
+  serialized_start=1336,
+  serialized_end=1367,
 )
 
 _INVITATION.fields_by_name['created_at'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP
 _INVITATION.fields_by_name['valid_until'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP
-_CREATEREQUEST.fields_by_name['valid_until'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP
+_CREATEREQUEST.fields_by_name['invitation'].message_type = _INVITATION
 _CREATERESPONSE.fields_by_name['invitation'].message_type = _INVITATION
 _GETRESPONSE.fields_by_name['invitation'].message_type = _INVITATION
 _UPDATEREQUEST.fields_by_name['sent'].message_type = google_dot_protobuf_dot_wrappers__pb2._BOOLVALUE
@@ -806,8 +778,8 @@ _INVITATIONS = _descriptor.ServiceDescriptor(
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=1450,
-  serialized_end=1847,
+  serialized_start=1370,
+  serialized_end=1767,
   methods=[
   _descriptor.MethodDescriptor(
     name='Create',
diff --git a/perxis/items/items_pb2.py b/perxis/items/items_pb2.py
new file mode 100644
index 0000000000000000000000000000000000000000..b29376b85138aa76a1ecc95ac72ad2e5eda0e107
--- /dev/null
+++ b/perxis/items/items_pb2.py
@@ -0,0 +1,1624 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: items/items.proto
+"""Generated protocol buffer code."""
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
+from common import common_pb2 as common_dot_common__pb2
+from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
+from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='items/items.proto',
+  package='content.items',
+  syntax='proto3',
+  serialized_options=b'Z,github.com/perxteam/perxis/proto/items;items',
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\x11items/items.proto\x12\rcontent.items\x1a\x1bgoogle/protobuf/empty.proto\x1a\x13\x63ommon/common.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1cgoogle/protobuf/struct.proto\"\xb1\x04\n\x04Item\x12\n\n\x02id\x18\x01 \x01(\t\x12\x10\n\x08space_id\x18\x02 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x03 \x01(\t\x12\x15\n\rcollection_id\x18\x04 \x01(\t\x12(\n\x05state\x18\x05 \x01(\x0e\x32\x19.content.items.Item.State\x12.\n\ncreated_at\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x12\n\ncreated_by\x18\x07 \x01(\t\x12%\n\x04\x64\x61ta\x18\x08 \x01(\x0b\x32\x17.google.protobuf.Struct\x12;\n\x0ctranslations\x18\t \x03(\x0b\x32%.content.items.Item.TranslationsEntry\x12\x13\n\x0brevision_id\x18\n \x01(\t\x12\x30\n\x0cpublished_at\x18\x0b \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x14\n\x0cpublished_by\x18\x0c \x01(\t\x12/\n\x0b\x61rchived_at\x18\r \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x13\n\x0b\x61rchived_by\x18\x0e \x01(\t\x1aL\n\x11TranslationsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.google.protobuf.Struct:\x02\x38\x01\"!\n\x05State\x12\t\n\x05\x44RAFT\x10\x00\x12\r\n\tPUBLISHED\x10\x01\"2\n\x06\x46ilter\x12\n\n\x02id\x18\x01 \x03(\t\x12\x1c\n\x04\x64\x61ta\x18\x02 \x03(\x0b\x32\x0e.common.Filter\"2\n\rCreateRequest\x12!\n\x04item\x18\x01 \x01(\x0b\x32\x13.content.items.Item\"6\n\x0e\x43reateResponse\x12$\n\x07\x63reated\x18\x01 \x01(\x0b\x32\x13.content.items.Item\"V\n\nGetRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x0f\n\x07item_id\x18\x04 \x01(\t\"0\n\x0bGetResponse\x12!\n\x04item\x18\x01 \x01(\x0b\x32\x13.content.items.Item\"\x93\x01\n\x0b\x46indRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12%\n\x06\x66ilter\x18\x04 \x01(\x0b\x32\x15.content.items.Filter\x12$\n\x07options\x18\x05 \x01(\x0b\x32\x13.common.FindOptions\"A\n\x0c\x46indResponse\x12\"\n\x05items\x18\x01 \x03(\x0b\x32\x13.content.items.Item\x12\r\n\x05total\x18\x02 \x01(\x05\"2\n\rUpdateRequest\x12!\n\x04item\x18\x01 \x01(\x0b\x32\x13.content.items.Item\"Y\n\rDeleteRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x0f\n\x07item_id\x18\x04 \x01(\t\"3\n\x0ePublishRequest\x12!\n\x04item\x18\x01 \x01(\x0b\x32\x13.content.items.Item\"\\\n\x10UnpublishRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x0f\n\x07item_id\x18\x04 \x01(\t\"r\n\x13GetPublishedRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x11\n\tlocale_id\x18\x04 \x01(\t\x12\x0f\n\x07item_id\x18\x05 \x01(\t\"9\n\x14GetPublishedResponse\x12!\n\x04item\x18\x01 \x01(\x0b\x32\x13.content.items.Item\"\xaf\x01\n\x14\x46indPublishedRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x11\n\tlocale_id\x18\x04 \x01(\t\x12%\n\x06\x66ilter\x18\x05 \x01(\x0b\x32\x15.content.items.Filter\x12$\n\x07options\x18\x06 \x01(\x0b\x32\x13.common.FindOptions\"J\n\x15\x46indPublishedResponse\x12\"\n\x05items\x18\x01 \x03(\x0b\x32\x13.content.items.Item\x12\r\n\x05total\x18\x02 \x01(\x05\"s\n\x12GetRevisionRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x0f\n\x07item_id\x18\x04 \x01(\t\x12\x13\n\x0brevision_id\x18\x05 \x01(\t\"8\n\x13GetRevisionResponse\x12!\n\x04item\x18\x01 \x01(\x0b\x32\x13.content.items.Item\"`\n\x14ListRevisionsRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x0f\n\x07item_id\x18\x04 \x01(\t\";\n\x15ListRevisionsResponse\x12\"\n\x05items\x18\x01 \x03(\x0b\x32\x13.content.items.Item\"3\n\x0e\x41rchiveRequest\x12!\n\x04item\x18\x01 \x01(\x0b\x32\x13.content.items.Item\"\\\n\x10UnarchiveRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x0f\n\x07item_id\x18\x04 \x01(\t\"\x9b\x01\n\x13\x46indArchivedRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12%\n\x06\x66ilter\x18\x05 \x01(\x0b\x32\x15.content.items.Filter\x12$\n\x07options\x18\x06 \x01(\x0b\x32\x13.common.FindOptions\"I\n\x14\x46indArchivedResponse\x12\"\n\x05items\x18\x01 \x03(\x0b\x32\x13.content.items.Item\x12\r\n\x05total\x18\x02 \x01(\x05\x32\xb9\x08\n\x05Items\x12G\n\x06\x43reate\x12\x1c.content.items.CreateRequest\x1a\x1d.content.items.CreateResponse\"\x00\x12>\n\x03Get\x12\x19.content.items.GetRequest\x1a\x1a.content.items.GetResponse\"\x00\x12\x41\n\x04\x46ind\x12\x1a.content.items.FindRequest\x1a\x1b.content.items.FindResponse\"\x00\x12@\n\x06Update\x12\x1c.content.items.UpdateRequest\x1a\x16.google.protobuf.Empty\"\x00\x12@\n\x06\x44\x65lete\x12\x1c.content.items.DeleteRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x42\n\x07Publish\x12\x1d.content.items.PublishRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x46\n\tUnpublish\x12\x1f.content.items.UnpublishRequest\x1a\x16.google.protobuf.Empty\"\x00\x12Y\n\x0cGetPublished\x12\".content.items.GetPublishedRequest\x1a#.content.items.GetPublishedResponse\"\x00\x12\\\n\rFindPublished\x12#.content.items.FindPublishedRequest\x1a$.content.items.FindPublishedResponse\"\x00\x12V\n\x0bGetRevision\x12!.content.items.GetRevisionRequest\x1a\".content.items.GetRevisionResponse\"\x00\x12\\\n\rListRevisions\x12#.content.items.ListRevisionsRequest\x1a$.content.items.ListRevisionsResponse\"\x00\x12\x42\n\x07\x41rchive\x12\x1d.content.items.ArchiveRequest\x1a\x16.google.protobuf.Empty\"\x00\x12Y\n\x0c\x46indArchived\x12\".content.items.FindArchivedRequest\x1a#.content.items.FindArchivedResponse\"\x00\x12\x46\n\tUnarchive\x12\x1f.content.items.UnarchiveRequest\x1a\x16.google.protobuf.Empty\"\x00\x42.Z,github.com/perxteam/perxis/proto/items;itemsb\x06proto3'
+  ,
+  dependencies=[google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,common_dot_common__pb2.DESCRIPTOR,google_dot_protobuf_dot_timestamp__pb2.DESCRIPTOR,google_dot_protobuf_dot_struct__pb2.DESCRIPTOR,])
+
+
+
+_ITEM_STATE = _descriptor.EnumDescriptor(
+  name='State',
+  full_name='content.items.Item.State',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='DRAFT', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='PUBLISHED', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=678,
+  serialized_end=711,
+)
+_sym_db.RegisterEnumDescriptor(_ITEM_STATE)
+
+
+_ITEM_TRANSLATIONSENTRY = _descriptor.Descriptor(
+  name='TranslationsEntry',
+  full_name='content.items.Item.TranslationsEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='content.items.Item.TranslationsEntry.key', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='content.items.Item.TranslationsEntry.value', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=b'8\001',
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=600,
+  serialized_end=676,
+)
+
+_ITEM = _descriptor.Descriptor(
+  name='Item',
+  full_name='content.items.Item',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='id', full_name='content.items.Item.id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='space_id', full_name='content.items.Item.space_id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='env_id', full_name='content.items.Item.env_id', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='collection_id', full_name='content.items.Item.collection_id', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='state', full_name='content.items.Item.state', index=4,
+      number=5, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='created_at', full_name='content.items.Item.created_at', index=5,
+      number=6, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='created_by', full_name='content.items.Item.created_by', index=6,
+      number=7, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='data', full_name='content.items.Item.data', index=7,
+      number=8, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='translations', full_name='content.items.Item.translations', index=8,
+      number=9, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='revision_id', full_name='content.items.Item.revision_id', index=9,
+      number=10, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='published_at', full_name='content.items.Item.published_at', index=10,
+      number=11, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='published_by', full_name='content.items.Item.published_by', index=11,
+      number=12, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='archived_at', full_name='content.items.Item.archived_at', index=12,
+      number=13, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='archived_by', full_name='content.items.Item.archived_by', index=13,
+      number=14, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[_ITEM_TRANSLATIONSENTRY, ],
+  enum_types=[
+    _ITEM_STATE,
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=150,
+  serialized_end=711,
+)
+
+
+_FILTER = _descriptor.Descriptor(
+  name='Filter',
+  full_name='content.items.Filter',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='id', full_name='content.items.Filter.id', index=0,
+      number=1, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='data', full_name='content.items.Filter.data', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=713,
+  serialized_end=763,
+)
+
+
+_CREATEREQUEST = _descriptor.Descriptor(
+  name='CreateRequest',
+  full_name='content.items.CreateRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='item', full_name='content.items.CreateRequest.item', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=765,
+  serialized_end=815,
+)
+
+
+_CREATERESPONSE = _descriptor.Descriptor(
+  name='CreateResponse',
+  full_name='content.items.CreateResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='created', full_name='content.items.CreateResponse.created', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=817,
+  serialized_end=871,
+)
+
+
+_GETREQUEST = _descriptor.Descriptor(
+  name='GetRequest',
+  full_name='content.items.GetRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='space_id', full_name='content.items.GetRequest.space_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='env_id', full_name='content.items.GetRequest.env_id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='collection_id', full_name='content.items.GetRequest.collection_id', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='item_id', full_name='content.items.GetRequest.item_id', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=873,
+  serialized_end=959,
+)
+
+
+_GETRESPONSE = _descriptor.Descriptor(
+  name='GetResponse',
+  full_name='content.items.GetResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='item', full_name='content.items.GetResponse.item', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=961,
+  serialized_end=1009,
+)
+
+
+_FINDREQUEST = _descriptor.Descriptor(
+  name='FindRequest',
+  full_name='content.items.FindRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='space_id', full_name='content.items.FindRequest.space_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='env_id', full_name='content.items.FindRequest.env_id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='collection_id', full_name='content.items.FindRequest.collection_id', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='filter', full_name='content.items.FindRequest.filter', index=3,
+      number=4, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='options', full_name='content.items.FindRequest.options', index=4,
+      number=5, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1012,
+  serialized_end=1159,
+)
+
+
+_FINDRESPONSE = _descriptor.Descriptor(
+  name='FindResponse',
+  full_name='content.items.FindResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='items', full_name='content.items.FindResponse.items', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='total', full_name='content.items.FindResponse.total', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1161,
+  serialized_end=1226,
+)
+
+
+_UPDATEREQUEST = _descriptor.Descriptor(
+  name='UpdateRequest',
+  full_name='content.items.UpdateRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='item', full_name='content.items.UpdateRequest.item', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1228,
+  serialized_end=1278,
+)
+
+
+_DELETEREQUEST = _descriptor.Descriptor(
+  name='DeleteRequest',
+  full_name='content.items.DeleteRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='space_id', full_name='content.items.DeleteRequest.space_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='env_id', full_name='content.items.DeleteRequest.env_id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='collection_id', full_name='content.items.DeleteRequest.collection_id', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='item_id', full_name='content.items.DeleteRequest.item_id', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1280,
+  serialized_end=1369,
+)
+
+
+_PUBLISHREQUEST = _descriptor.Descriptor(
+  name='PublishRequest',
+  full_name='content.items.PublishRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='item', full_name='content.items.PublishRequest.item', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1371,
+  serialized_end=1422,
+)
+
+
+_UNPUBLISHREQUEST = _descriptor.Descriptor(
+  name='UnpublishRequest',
+  full_name='content.items.UnpublishRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='space_id', full_name='content.items.UnpublishRequest.space_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='env_id', full_name='content.items.UnpublishRequest.env_id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='collection_id', full_name='content.items.UnpublishRequest.collection_id', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='item_id', full_name='content.items.UnpublishRequest.item_id', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1424,
+  serialized_end=1516,
+)
+
+
+_GETPUBLISHEDREQUEST = _descriptor.Descriptor(
+  name='GetPublishedRequest',
+  full_name='content.items.GetPublishedRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='space_id', full_name='content.items.GetPublishedRequest.space_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='env_id', full_name='content.items.GetPublishedRequest.env_id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='collection_id', full_name='content.items.GetPublishedRequest.collection_id', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='locale_id', full_name='content.items.GetPublishedRequest.locale_id', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='item_id', full_name='content.items.GetPublishedRequest.item_id', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1518,
+  serialized_end=1632,
+)
+
+
+_GETPUBLISHEDRESPONSE = _descriptor.Descriptor(
+  name='GetPublishedResponse',
+  full_name='content.items.GetPublishedResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='item', full_name='content.items.GetPublishedResponse.item', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1634,
+  serialized_end=1691,
+)
+
+
+_FINDPUBLISHEDREQUEST = _descriptor.Descriptor(
+  name='FindPublishedRequest',
+  full_name='content.items.FindPublishedRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='space_id', full_name='content.items.FindPublishedRequest.space_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='env_id', full_name='content.items.FindPublishedRequest.env_id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='collection_id', full_name='content.items.FindPublishedRequest.collection_id', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='locale_id', full_name='content.items.FindPublishedRequest.locale_id', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='filter', full_name='content.items.FindPublishedRequest.filter', index=4,
+      number=5, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='options', full_name='content.items.FindPublishedRequest.options', index=5,
+      number=6, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1694,
+  serialized_end=1869,
+)
+
+
+_FINDPUBLISHEDRESPONSE = _descriptor.Descriptor(
+  name='FindPublishedResponse',
+  full_name='content.items.FindPublishedResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='items', full_name='content.items.FindPublishedResponse.items', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='total', full_name='content.items.FindPublishedResponse.total', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1871,
+  serialized_end=1945,
+)
+
+
+_GETREVISIONREQUEST = _descriptor.Descriptor(
+  name='GetRevisionRequest',
+  full_name='content.items.GetRevisionRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='space_id', full_name='content.items.GetRevisionRequest.space_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='env_id', full_name='content.items.GetRevisionRequest.env_id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='collection_id', full_name='content.items.GetRevisionRequest.collection_id', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='item_id', full_name='content.items.GetRevisionRequest.item_id', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='revision_id', full_name='content.items.GetRevisionRequest.revision_id', index=4,
+      number=5, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1947,
+  serialized_end=2062,
+)
+
+
+_GETREVISIONRESPONSE = _descriptor.Descriptor(
+  name='GetRevisionResponse',
+  full_name='content.items.GetRevisionResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='item', full_name='content.items.GetRevisionResponse.item', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2064,
+  serialized_end=2120,
+)
+
+
+_LISTREVISIONSREQUEST = _descriptor.Descriptor(
+  name='ListRevisionsRequest',
+  full_name='content.items.ListRevisionsRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='space_id', full_name='content.items.ListRevisionsRequest.space_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='env_id', full_name='content.items.ListRevisionsRequest.env_id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='collection_id', full_name='content.items.ListRevisionsRequest.collection_id', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='item_id', full_name='content.items.ListRevisionsRequest.item_id', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2122,
+  serialized_end=2218,
+)
+
+
+_LISTREVISIONSRESPONSE = _descriptor.Descriptor(
+  name='ListRevisionsResponse',
+  full_name='content.items.ListRevisionsResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='items', full_name='content.items.ListRevisionsResponse.items', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2220,
+  serialized_end=2279,
+)
+
+
+_ARCHIVEREQUEST = _descriptor.Descriptor(
+  name='ArchiveRequest',
+  full_name='content.items.ArchiveRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='item', full_name='content.items.ArchiveRequest.item', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2281,
+  serialized_end=2332,
+)
+
+
+_UNARCHIVEREQUEST = _descriptor.Descriptor(
+  name='UnarchiveRequest',
+  full_name='content.items.UnarchiveRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='space_id', full_name='content.items.UnarchiveRequest.space_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='env_id', full_name='content.items.UnarchiveRequest.env_id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='collection_id', full_name='content.items.UnarchiveRequest.collection_id', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='item_id', full_name='content.items.UnarchiveRequest.item_id', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2334,
+  serialized_end=2426,
+)
+
+
+_FINDARCHIVEDREQUEST = _descriptor.Descriptor(
+  name='FindArchivedRequest',
+  full_name='content.items.FindArchivedRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='space_id', full_name='content.items.FindArchivedRequest.space_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='env_id', full_name='content.items.FindArchivedRequest.env_id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='collection_id', full_name='content.items.FindArchivedRequest.collection_id', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='filter', full_name='content.items.FindArchivedRequest.filter', index=3,
+      number=5, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='options', full_name='content.items.FindArchivedRequest.options', index=4,
+      number=6, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2429,
+  serialized_end=2584,
+)
+
+
+_FINDARCHIVEDRESPONSE = _descriptor.Descriptor(
+  name='FindArchivedResponse',
+  full_name='content.items.FindArchivedResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='items', full_name='content.items.FindArchivedResponse.items', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='total', full_name='content.items.FindArchivedResponse.total', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2586,
+  serialized_end=2659,
+)
+
+_ITEM_TRANSLATIONSENTRY.fields_by_name['value'].message_type = google_dot_protobuf_dot_struct__pb2._STRUCT
+_ITEM_TRANSLATIONSENTRY.containing_type = _ITEM
+_ITEM.fields_by_name['state'].enum_type = _ITEM_STATE
+_ITEM.fields_by_name['created_at'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP
+_ITEM.fields_by_name['data'].message_type = google_dot_protobuf_dot_struct__pb2._STRUCT
+_ITEM.fields_by_name['translations'].message_type = _ITEM_TRANSLATIONSENTRY
+_ITEM.fields_by_name['published_at'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP
+_ITEM.fields_by_name['archived_at'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP
+_ITEM_STATE.containing_type = _ITEM
+_FILTER.fields_by_name['data'].message_type = common_dot_common__pb2._FILTER
+_CREATEREQUEST.fields_by_name['item'].message_type = _ITEM
+_CREATERESPONSE.fields_by_name['created'].message_type = _ITEM
+_GETRESPONSE.fields_by_name['item'].message_type = _ITEM
+_FINDREQUEST.fields_by_name['filter'].message_type = _FILTER
+_FINDREQUEST.fields_by_name['options'].message_type = common_dot_common__pb2._FINDOPTIONS
+_FINDRESPONSE.fields_by_name['items'].message_type = _ITEM
+_UPDATEREQUEST.fields_by_name['item'].message_type = _ITEM
+_PUBLISHREQUEST.fields_by_name['item'].message_type = _ITEM
+_GETPUBLISHEDRESPONSE.fields_by_name['item'].message_type = _ITEM
+_FINDPUBLISHEDREQUEST.fields_by_name['filter'].message_type = _FILTER
+_FINDPUBLISHEDREQUEST.fields_by_name['options'].message_type = common_dot_common__pb2._FINDOPTIONS
+_FINDPUBLISHEDRESPONSE.fields_by_name['items'].message_type = _ITEM
+_GETREVISIONRESPONSE.fields_by_name['item'].message_type = _ITEM
+_LISTREVISIONSRESPONSE.fields_by_name['items'].message_type = _ITEM
+_ARCHIVEREQUEST.fields_by_name['item'].message_type = _ITEM
+_FINDARCHIVEDREQUEST.fields_by_name['filter'].message_type = _FILTER
+_FINDARCHIVEDREQUEST.fields_by_name['options'].message_type = common_dot_common__pb2._FINDOPTIONS
+_FINDARCHIVEDRESPONSE.fields_by_name['items'].message_type = _ITEM
+DESCRIPTOR.message_types_by_name['Item'] = _ITEM
+DESCRIPTOR.message_types_by_name['Filter'] = _FILTER
+DESCRIPTOR.message_types_by_name['CreateRequest'] = _CREATEREQUEST
+DESCRIPTOR.message_types_by_name['CreateResponse'] = _CREATERESPONSE
+DESCRIPTOR.message_types_by_name['GetRequest'] = _GETREQUEST
+DESCRIPTOR.message_types_by_name['GetResponse'] = _GETRESPONSE
+DESCRIPTOR.message_types_by_name['FindRequest'] = _FINDREQUEST
+DESCRIPTOR.message_types_by_name['FindResponse'] = _FINDRESPONSE
+DESCRIPTOR.message_types_by_name['UpdateRequest'] = _UPDATEREQUEST
+DESCRIPTOR.message_types_by_name['DeleteRequest'] = _DELETEREQUEST
+DESCRIPTOR.message_types_by_name['PublishRequest'] = _PUBLISHREQUEST
+DESCRIPTOR.message_types_by_name['UnpublishRequest'] = _UNPUBLISHREQUEST
+DESCRIPTOR.message_types_by_name['GetPublishedRequest'] = _GETPUBLISHEDREQUEST
+DESCRIPTOR.message_types_by_name['GetPublishedResponse'] = _GETPUBLISHEDRESPONSE
+DESCRIPTOR.message_types_by_name['FindPublishedRequest'] = _FINDPUBLISHEDREQUEST
+DESCRIPTOR.message_types_by_name['FindPublishedResponse'] = _FINDPUBLISHEDRESPONSE
+DESCRIPTOR.message_types_by_name['GetRevisionRequest'] = _GETREVISIONREQUEST
+DESCRIPTOR.message_types_by_name['GetRevisionResponse'] = _GETREVISIONRESPONSE
+DESCRIPTOR.message_types_by_name['ListRevisionsRequest'] = _LISTREVISIONSREQUEST
+DESCRIPTOR.message_types_by_name['ListRevisionsResponse'] = _LISTREVISIONSRESPONSE
+DESCRIPTOR.message_types_by_name['ArchiveRequest'] = _ARCHIVEREQUEST
+DESCRIPTOR.message_types_by_name['UnarchiveRequest'] = _UNARCHIVEREQUEST
+DESCRIPTOR.message_types_by_name['FindArchivedRequest'] = _FINDARCHIVEDREQUEST
+DESCRIPTOR.message_types_by_name['FindArchivedResponse'] = _FINDARCHIVEDRESPONSE
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+Item = _reflection.GeneratedProtocolMessageType('Item', (_message.Message,), {
+
+  'TranslationsEntry' : _reflection.GeneratedProtocolMessageType('TranslationsEntry', (_message.Message,), {
+    'DESCRIPTOR' : _ITEM_TRANSLATIONSENTRY,
+    '__module__' : 'items.items_pb2'
+    # @@protoc_insertion_point(class_scope:content.items.Item.TranslationsEntry)
+    })
+  ,
+  'DESCRIPTOR' : _ITEM,
+  '__module__' : 'items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.Item)
+  })
+_sym_db.RegisterMessage(Item)
+_sym_db.RegisterMessage(Item.TranslationsEntry)
+
+Filter = _reflection.GeneratedProtocolMessageType('Filter', (_message.Message,), {
+  'DESCRIPTOR' : _FILTER,
+  '__module__' : 'items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.Filter)
+  })
+_sym_db.RegisterMessage(Filter)
+
+CreateRequest = _reflection.GeneratedProtocolMessageType('CreateRequest', (_message.Message,), {
+  'DESCRIPTOR' : _CREATEREQUEST,
+  '__module__' : 'items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.CreateRequest)
+  })
+_sym_db.RegisterMessage(CreateRequest)
+
+CreateResponse = _reflection.GeneratedProtocolMessageType('CreateResponse', (_message.Message,), {
+  'DESCRIPTOR' : _CREATERESPONSE,
+  '__module__' : 'items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.CreateResponse)
+  })
+_sym_db.RegisterMessage(CreateResponse)
+
+GetRequest = _reflection.GeneratedProtocolMessageType('GetRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETREQUEST,
+  '__module__' : 'items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.GetRequest)
+  })
+_sym_db.RegisterMessage(GetRequest)
+
+GetResponse = _reflection.GeneratedProtocolMessageType('GetResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GETRESPONSE,
+  '__module__' : 'items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.GetResponse)
+  })
+_sym_db.RegisterMessage(GetResponse)
+
+FindRequest = _reflection.GeneratedProtocolMessageType('FindRequest', (_message.Message,), {
+  'DESCRIPTOR' : _FINDREQUEST,
+  '__module__' : 'items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.FindRequest)
+  })
+_sym_db.RegisterMessage(FindRequest)
+
+FindResponse = _reflection.GeneratedProtocolMessageType('FindResponse', (_message.Message,), {
+  'DESCRIPTOR' : _FINDRESPONSE,
+  '__module__' : 'items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.FindResponse)
+  })
+_sym_db.RegisterMessage(FindResponse)
+
+UpdateRequest = _reflection.GeneratedProtocolMessageType('UpdateRequest', (_message.Message,), {
+  'DESCRIPTOR' : _UPDATEREQUEST,
+  '__module__' : 'items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.UpdateRequest)
+  })
+_sym_db.RegisterMessage(UpdateRequest)
+
+DeleteRequest = _reflection.GeneratedProtocolMessageType('DeleteRequest', (_message.Message,), {
+  'DESCRIPTOR' : _DELETEREQUEST,
+  '__module__' : 'items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.DeleteRequest)
+  })
+_sym_db.RegisterMessage(DeleteRequest)
+
+PublishRequest = _reflection.GeneratedProtocolMessageType('PublishRequest', (_message.Message,), {
+  'DESCRIPTOR' : _PUBLISHREQUEST,
+  '__module__' : 'items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.PublishRequest)
+  })
+_sym_db.RegisterMessage(PublishRequest)
+
+UnpublishRequest = _reflection.GeneratedProtocolMessageType('UnpublishRequest', (_message.Message,), {
+  'DESCRIPTOR' : _UNPUBLISHREQUEST,
+  '__module__' : 'items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.UnpublishRequest)
+  })
+_sym_db.RegisterMessage(UnpublishRequest)
+
+GetPublishedRequest = _reflection.GeneratedProtocolMessageType('GetPublishedRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETPUBLISHEDREQUEST,
+  '__module__' : 'items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.GetPublishedRequest)
+  })
+_sym_db.RegisterMessage(GetPublishedRequest)
+
+GetPublishedResponse = _reflection.GeneratedProtocolMessageType('GetPublishedResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GETPUBLISHEDRESPONSE,
+  '__module__' : 'items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.GetPublishedResponse)
+  })
+_sym_db.RegisterMessage(GetPublishedResponse)
+
+FindPublishedRequest = _reflection.GeneratedProtocolMessageType('FindPublishedRequest', (_message.Message,), {
+  'DESCRIPTOR' : _FINDPUBLISHEDREQUEST,
+  '__module__' : 'items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.FindPublishedRequest)
+  })
+_sym_db.RegisterMessage(FindPublishedRequest)
+
+FindPublishedResponse = _reflection.GeneratedProtocolMessageType('FindPublishedResponse', (_message.Message,), {
+  'DESCRIPTOR' : _FINDPUBLISHEDRESPONSE,
+  '__module__' : 'items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.FindPublishedResponse)
+  })
+_sym_db.RegisterMessage(FindPublishedResponse)
+
+GetRevisionRequest = _reflection.GeneratedProtocolMessageType('GetRevisionRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETREVISIONREQUEST,
+  '__module__' : 'items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.GetRevisionRequest)
+  })
+_sym_db.RegisterMessage(GetRevisionRequest)
+
+GetRevisionResponse = _reflection.GeneratedProtocolMessageType('GetRevisionResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GETREVISIONRESPONSE,
+  '__module__' : 'items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.GetRevisionResponse)
+  })
+_sym_db.RegisterMessage(GetRevisionResponse)
+
+ListRevisionsRequest = _reflection.GeneratedProtocolMessageType('ListRevisionsRequest', (_message.Message,), {
+  'DESCRIPTOR' : _LISTREVISIONSREQUEST,
+  '__module__' : 'items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.ListRevisionsRequest)
+  })
+_sym_db.RegisterMessage(ListRevisionsRequest)
+
+ListRevisionsResponse = _reflection.GeneratedProtocolMessageType('ListRevisionsResponse', (_message.Message,), {
+  'DESCRIPTOR' : _LISTREVISIONSRESPONSE,
+  '__module__' : 'items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.ListRevisionsResponse)
+  })
+_sym_db.RegisterMessage(ListRevisionsResponse)
+
+ArchiveRequest = _reflection.GeneratedProtocolMessageType('ArchiveRequest', (_message.Message,), {
+  'DESCRIPTOR' : _ARCHIVEREQUEST,
+  '__module__' : 'items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.ArchiveRequest)
+  })
+_sym_db.RegisterMessage(ArchiveRequest)
+
+UnarchiveRequest = _reflection.GeneratedProtocolMessageType('UnarchiveRequest', (_message.Message,), {
+  'DESCRIPTOR' : _UNARCHIVEREQUEST,
+  '__module__' : 'items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.UnarchiveRequest)
+  })
+_sym_db.RegisterMessage(UnarchiveRequest)
+
+FindArchivedRequest = _reflection.GeneratedProtocolMessageType('FindArchivedRequest', (_message.Message,), {
+  'DESCRIPTOR' : _FINDARCHIVEDREQUEST,
+  '__module__' : 'items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.FindArchivedRequest)
+  })
+_sym_db.RegisterMessage(FindArchivedRequest)
+
+FindArchivedResponse = _reflection.GeneratedProtocolMessageType('FindArchivedResponse', (_message.Message,), {
+  'DESCRIPTOR' : _FINDARCHIVEDRESPONSE,
+  '__module__' : 'items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.FindArchivedResponse)
+  })
+_sym_db.RegisterMessage(FindArchivedResponse)
+
+
+DESCRIPTOR._options = None
+_ITEM_TRANSLATIONSENTRY._options = None
+
+_ITEMS = _descriptor.ServiceDescriptor(
+  name='Items',
+  full_name='content.items.Items',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_start=2662,
+  serialized_end=3743,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='Create',
+    full_name='content.items.Items.Create',
+    index=0,
+    containing_service=None,
+    input_type=_CREATEREQUEST,
+    output_type=_CREATERESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='Get',
+    full_name='content.items.Items.Get',
+    index=1,
+    containing_service=None,
+    input_type=_GETREQUEST,
+    output_type=_GETRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='Find',
+    full_name='content.items.Items.Find',
+    index=2,
+    containing_service=None,
+    input_type=_FINDREQUEST,
+    output_type=_FINDRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='Update',
+    full_name='content.items.Items.Update',
+    index=3,
+    containing_service=None,
+    input_type=_UPDATEREQUEST,
+    output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='Delete',
+    full_name='content.items.Items.Delete',
+    index=4,
+    containing_service=None,
+    input_type=_DELETEREQUEST,
+    output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='Publish',
+    full_name='content.items.Items.Publish',
+    index=5,
+    containing_service=None,
+    input_type=_PUBLISHREQUEST,
+    output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='Unpublish',
+    full_name='content.items.Items.Unpublish',
+    index=6,
+    containing_service=None,
+    input_type=_UNPUBLISHREQUEST,
+    output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetPublished',
+    full_name='content.items.Items.GetPublished',
+    index=7,
+    containing_service=None,
+    input_type=_GETPUBLISHEDREQUEST,
+    output_type=_GETPUBLISHEDRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='FindPublished',
+    full_name='content.items.Items.FindPublished',
+    index=8,
+    containing_service=None,
+    input_type=_FINDPUBLISHEDREQUEST,
+    output_type=_FINDPUBLISHEDRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetRevision',
+    full_name='content.items.Items.GetRevision',
+    index=9,
+    containing_service=None,
+    input_type=_GETREVISIONREQUEST,
+    output_type=_GETREVISIONRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListRevisions',
+    full_name='content.items.Items.ListRevisions',
+    index=10,
+    containing_service=None,
+    input_type=_LISTREVISIONSREQUEST,
+    output_type=_LISTREVISIONSRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='Archive',
+    full_name='content.items.Items.Archive',
+    index=11,
+    containing_service=None,
+    input_type=_ARCHIVEREQUEST,
+    output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='FindArchived',
+    full_name='content.items.Items.FindArchived',
+    index=12,
+    containing_service=None,
+    input_type=_FINDARCHIVEDREQUEST,
+    output_type=_FINDARCHIVEDRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='Unarchive',
+    full_name='content.items.Items.Unarchive',
+    index=13,
+    containing_service=None,
+    input_type=_UNARCHIVEREQUEST,
+    output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_ITEMS)
+
+DESCRIPTOR.services_by_name['Items'] = _ITEMS
+
+# @@protoc_insertion_point(module_scope)
diff --git a/perxis/items/items_pb2_grpc.py b/perxis/items/items_pb2_grpc.py
new file mode 100644
index 0000000000000000000000000000000000000000..ba84d90297f06fa78c6ce31faf27f3a8599deecc
--- /dev/null
+++ b/perxis/items/items_pb2_grpc.py
@@ -0,0 +1,496 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+"""Client and server classes corresponding to protobuf-defined services."""
+import grpc
+
+from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
+from items import items_pb2 as items_dot_items__pb2
+
+
+class ItemsStub(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def __init__(self, channel):
+        """Constructor.
+
+        Args:
+            channel: A grpc.Channel.
+        """
+        self.Create = channel.unary_unary(
+                '/content.items.Items/Create',
+                request_serializer=items_dot_items__pb2.CreateRequest.SerializeToString,
+                response_deserializer=items_dot_items__pb2.CreateResponse.FromString,
+                )
+        self.Get = channel.unary_unary(
+                '/content.items.Items/Get',
+                request_serializer=items_dot_items__pb2.GetRequest.SerializeToString,
+                response_deserializer=items_dot_items__pb2.GetResponse.FromString,
+                )
+        self.Find = channel.unary_unary(
+                '/content.items.Items/Find',
+                request_serializer=items_dot_items__pb2.FindRequest.SerializeToString,
+                response_deserializer=items_dot_items__pb2.FindResponse.FromString,
+                )
+        self.Update = channel.unary_unary(
+                '/content.items.Items/Update',
+                request_serializer=items_dot_items__pb2.UpdateRequest.SerializeToString,
+                response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+                )
+        self.Delete = channel.unary_unary(
+                '/content.items.Items/Delete',
+                request_serializer=items_dot_items__pb2.DeleteRequest.SerializeToString,
+                response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+                )
+        self.Publish = channel.unary_unary(
+                '/content.items.Items/Publish',
+                request_serializer=items_dot_items__pb2.PublishRequest.SerializeToString,
+                response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+                )
+        self.Unpublish = channel.unary_unary(
+                '/content.items.Items/Unpublish',
+                request_serializer=items_dot_items__pb2.UnpublishRequest.SerializeToString,
+                response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+                )
+        self.GetPublished = channel.unary_unary(
+                '/content.items.Items/GetPublished',
+                request_serializer=items_dot_items__pb2.GetPublishedRequest.SerializeToString,
+                response_deserializer=items_dot_items__pb2.GetPublishedResponse.FromString,
+                )
+        self.FindPublished = channel.unary_unary(
+                '/content.items.Items/FindPublished',
+                request_serializer=items_dot_items__pb2.FindPublishedRequest.SerializeToString,
+                response_deserializer=items_dot_items__pb2.FindPublishedResponse.FromString,
+                )
+        self.GetRevision = channel.unary_unary(
+                '/content.items.Items/GetRevision',
+                request_serializer=items_dot_items__pb2.GetRevisionRequest.SerializeToString,
+                response_deserializer=items_dot_items__pb2.GetRevisionResponse.FromString,
+                )
+        self.ListRevisions = channel.unary_unary(
+                '/content.items.Items/ListRevisions',
+                request_serializer=items_dot_items__pb2.ListRevisionsRequest.SerializeToString,
+                response_deserializer=items_dot_items__pb2.ListRevisionsResponse.FromString,
+                )
+        self.Archive = channel.unary_unary(
+                '/content.items.Items/Archive',
+                request_serializer=items_dot_items__pb2.ArchiveRequest.SerializeToString,
+                response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+                )
+        self.FindArchived = channel.unary_unary(
+                '/content.items.Items/FindArchived',
+                request_serializer=items_dot_items__pb2.FindArchivedRequest.SerializeToString,
+                response_deserializer=items_dot_items__pb2.FindArchivedResponse.FromString,
+                )
+        self.Unarchive = channel.unary_unary(
+                '/content.items.Items/Unarchive',
+                request_serializer=items_dot_items__pb2.UnarchiveRequest.SerializeToString,
+                response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+                )
+
+
+class ItemsServicer(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def Create(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def Get(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def Find(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def Update(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def Delete(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def Publish(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def Unpublish(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def GetPublished(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def FindPublished(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def GetRevision(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def ListRevisions(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def Archive(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def FindArchived(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def Unarchive(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+
+def add_ItemsServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+            'Create': grpc.unary_unary_rpc_method_handler(
+                    servicer.Create,
+                    request_deserializer=items_dot_items__pb2.CreateRequest.FromString,
+                    response_serializer=items_dot_items__pb2.CreateResponse.SerializeToString,
+            ),
+            'Get': grpc.unary_unary_rpc_method_handler(
+                    servicer.Get,
+                    request_deserializer=items_dot_items__pb2.GetRequest.FromString,
+                    response_serializer=items_dot_items__pb2.GetResponse.SerializeToString,
+            ),
+            'Find': grpc.unary_unary_rpc_method_handler(
+                    servicer.Find,
+                    request_deserializer=items_dot_items__pb2.FindRequest.FromString,
+                    response_serializer=items_dot_items__pb2.FindResponse.SerializeToString,
+            ),
+            'Update': grpc.unary_unary_rpc_method_handler(
+                    servicer.Update,
+                    request_deserializer=items_dot_items__pb2.UpdateRequest.FromString,
+                    response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
+            ),
+            'Delete': grpc.unary_unary_rpc_method_handler(
+                    servicer.Delete,
+                    request_deserializer=items_dot_items__pb2.DeleteRequest.FromString,
+                    response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
+            ),
+            'Publish': grpc.unary_unary_rpc_method_handler(
+                    servicer.Publish,
+                    request_deserializer=items_dot_items__pb2.PublishRequest.FromString,
+                    response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
+            ),
+            'Unpublish': grpc.unary_unary_rpc_method_handler(
+                    servicer.Unpublish,
+                    request_deserializer=items_dot_items__pb2.UnpublishRequest.FromString,
+                    response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
+            ),
+            'GetPublished': grpc.unary_unary_rpc_method_handler(
+                    servicer.GetPublished,
+                    request_deserializer=items_dot_items__pb2.GetPublishedRequest.FromString,
+                    response_serializer=items_dot_items__pb2.GetPublishedResponse.SerializeToString,
+            ),
+            'FindPublished': grpc.unary_unary_rpc_method_handler(
+                    servicer.FindPublished,
+                    request_deserializer=items_dot_items__pb2.FindPublishedRequest.FromString,
+                    response_serializer=items_dot_items__pb2.FindPublishedResponse.SerializeToString,
+            ),
+            'GetRevision': grpc.unary_unary_rpc_method_handler(
+                    servicer.GetRevision,
+                    request_deserializer=items_dot_items__pb2.GetRevisionRequest.FromString,
+                    response_serializer=items_dot_items__pb2.GetRevisionResponse.SerializeToString,
+            ),
+            'ListRevisions': grpc.unary_unary_rpc_method_handler(
+                    servicer.ListRevisions,
+                    request_deserializer=items_dot_items__pb2.ListRevisionsRequest.FromString,
+                    response_serializer=items_dot_items__pb2.ListRevisionsResponse.SerializeToString,
+            ),
+            'Archive': grpc.unary_unary_rpc_method_handler(
+                    servicer.Archive,
+                    request_deserializer=items_dot_items__pb2.ArchiveRequest.FromString,
+                    response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
+            ),
+            'FindArchived': grpc.unary_unary_rpc_method_handler(
+                    servicer.FindArchived,
+                    request_deserializer=items_dot_items__pb2.FindArchivedRequest.FromString,
+                    response_serializer=items_dot_items__pb2.FindArchivedResponse.SerializeToString,
+            ),
+            'Unarchive': grpc.unary_unary_rpc_method_handler(
+                    servicer.Unarchive,
+                    request_deserializer=items_dot_items__pb2.UnarchiveRequest.FromString,
+                    response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
+            ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+            'content.items.Items', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+ # This class is part of an EXPERIMENTAL API.
+class Items(object):
+    """Missing associated documentation comment in .proto file."""
+
+    @staticmethod
+    def Create(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.items.Items/Create',
+            items_dot_items__pb2.CreateRequest.SerializeToString,
+            items_dot_items__pb2.CreateResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def Get(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.items.Items/Get',
+            items_dot_items__pb2.GetRequest.SerializeToString,
+            items_dot_items__pb2.GetResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def Find(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.items.Items/Find',
+            items_dot_items__pb2.FindRequest.SerializeToString,
+            items_dot_items__pb2.FindResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def Update(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.items.Items/Update',
+            items_dot_items__pb2.UpdateRequest.SerializeToString,
+            google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def Delete(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.items.Items/Delete',
+            items_dot_items__pb2.DeleteRequest.SerializeToString,
+            google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def Publish(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.items.Items/Publish',
+            items_dot_items__pb2.PublishRequest.SerializeToString,
+            google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def Unpublish(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.items.Items/Unpublish',
+            items_dot_items__pb2.UnpublishRequest.SerializeToString,
+            google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def GetPublished(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.items.Items/GetPublished',
+            items_dot_items__pb2.GetPublishedRequest.SerializeToString,
+            items_dot_items__pb2.GetPublishedResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def FindPublished(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.items.Items/FindPublished',
+            items_dot_items__pb2.FindPublishedRequest.SerializeToString,
+            items_dot_items__pb2.FindPublishedResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def GetRevision(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.items.Items/GetRevision',
+            items_dot_items__pb2.GetRevisionRequest.SerializeToString,
+            items_dot_items__pb2.GetRevisionResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def ListRevisions(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.items.Items/ListRevisions',
+            items_dot_items__pb2.ListRevisionsRequest.SerializeToString,
+            items_dot_items__pb2.ListRevisionsResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def Archive(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.items.Items/Archive',
+            items_dot_items__pb2.ArchiveRequest.SerializeToString,
+            google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def FindArchived(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.items.Items/FindArchived',
+            items_dot_items__pb2.FindArchivedRequest.SerializeToString,
+            items_dot_items__pb2.FindArchivedResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def Unarchive(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.items.Items/Unarchive',
+            items_dot_items__pb2.UnarchiveRequest.SerializeToString,
+            google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/perxis/locales/locales_pb2.py b/perxis/locales/locales_pb2.py
index fe9d5199621370e2ab29ae879cffa2bfec08ed72..d162bea78ebaa244067dfe6b96a7d21f6a93081c 100644
--- a/perxis/locales/locales_pb2.py
+++ b/perxis/locales/locales_pb2.py
@@ -20,7 +20,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=b'Z0github.com/perxteam/perxis/proto/locales;locales',
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\x15locales/locales.proto\x12\x0f\x63ontent.locales\x1a\x1bgoogle/protobuf/empty.proto\"4\n\x06Locale\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x10\n\x08space_id\x18\x03 \x01(\t\"B\n\rCreateRequest\x12\x11\n\tlocale_id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x10\n\x08space_id\x18\x03 \x01(\t\"9\n\x0e\x43reateResponse\x12\'\n\x06locale\x18\x01 \x01(\x0b\x32\x17.content.locales.Locale\"\x1f\n\x0bListRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\"8\n\x0cListResponse\x12(\n\x07locales\x18\x01 \x03(\x0b\x32\x17.content.locales.Locale\"4\n\rDeleteRequest\x12\x11\n\tlocale_id\x18\x01 \x01(\t\x12\x10\n\x08space_id\x18\x02 \x01(\t2\xe1\x01\n\x07Locales\x12K\n\x06\x43reate\x12\x1e.content.locales.CreateRequest\x1a\x1f.content.locales.CreateResponse\"\x00\x12\x45\n\x04List\x12\x1c.content.locales.ListRequest\x1a\x1d.content.locales.ListResponse\"\x00\x12\x42\n\x06\x44\x65lete\x12\x1e.content.locales.DeleteRequest\x1a\x16.google.protobuf.Empty\"\x00\x42\x32Z0github.com/perxteam/perxis/proto/locales;localesb\x06proto3'
+  serialized_pb=b'\n\x15locales/locales.proto\x12\x0f\x63ontent.locales\x1a\x1bgoogle/protobuf/empty.proto\"4\n\x06Locale\x12\n\n\x02id\x18\x01 \x01(\t\x12\x10\n\x08space_id\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\"8\n\rCreateRequest\x12\'\n\x06locale\x18\x01 \x01(\x0b\x32\x17.content.locales.Locale\"9\n\x0e\x43reateResponse\x12\'\n\x06locale\x18\x01 \x01(\x0b\x32\x17.content.locales.Locale\"\x1f\n\x0bListRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\"8\n\x0cListResponse\x12(\n\x07locales\x18\x01 \x03(\x0b\x32\x17.content.locales.Locale\"4\n\rDeleteRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x11\n\tlocale_id\x18\x02 \x01(\t2\xe1\x01\n\x07Locales\x12K\n\x06\x43reate\x12\x1e.content.locales.CreateRequest\x1a\x1f.content.locales.CreateResponse\"\x00\x12\x45\n\x04List\x12\x1c.content.locales.ListRequest\x1a\x1d.content.locales.ListResponse\"\x00\x12\x42\n\x06\x44\x65lete\x12\x1e.content.locales.DeleteRequest\x1a\x16.google.protobuf.Empty\"\x00\x42\x32Z0github.com/perxteam/perxis/proto/locales;localesb\x06proto3'
   ,
   dependencies=[google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,])
 
@@ -43,14 +43,14 @@ _LOCALE = _descriptor.Descriptor(
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='name', full_name='content.locales.Locale.name', index=1,
+      name='space_id', full_name='content.locales.Locale.space_id', index=1,
       number=2, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='space_id', full_name='content.locales.Locale.space_id', index=2,
+      name='name', full_name='content.locales.Locale.name', index=2,
       number=3, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
@@ -82,23 +82,9 @@ _CREATEREQUEST = _descriptor.Descriptor(
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='locale_id', full_name='content.locales.CreateRequest.locale_id', index=0,
-      number=1, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='name', full_name='content.locales.CreateRequest.name', index=1,
-      number=2, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='space_id', full_name='content.locales.CreateRequest.space_id', index=2,
-      number=3, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
+      name='locale', full_name='content.locales.CreateRequest.locale', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
@@ -115,7 +101,7 @@ _CREATEREQUEST = _descriptor.Descriptor(
   oneofs=[
   ],
   serialized_start=125,
-  serialized_end=191,
+  serialized_end=181,
 )
 
 
@@ -146,8 +132,8 @@ _CREATERESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=193,
-  serialized_end=250,
+  serialized_start=183,
+  serialized_end=240,
 )
 
 
@@ -178,8 +164,8 @@ _LISTREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=252,
-  serialized_end=283,
+  serialized_start=242,
+  serialized_end=273,
 )
 
 
@@ -210,8 +196,8 @@ _LISTRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=285,
-  serialized_end=341,
+  serialized_start=275,
+  serialized_end=331,
 )
 
 
@@ -224,14 +210,14 @@ _DELETEREQUEST = _descriptor.Descriptor(
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='locale_id', full_name='content.locales.DeleteRequest.locale_id', index=0,
+      name='space_id', full_name='content.locales.DeleteRequest.space_id', index=0,
       number=1, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='space_id', full_name='content.locales.DeleteRequest.space_id', index=1,
+      name='locale_id', full_name='content.locales.DeleteRequest.locale_id', index=1,
       number=2, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
@@ -249,10 +235,11 @@ _DELETEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=343,
-  serialized_end=395,
+  serialized_start=333,
+  serialized_end=385,
 )
 
+_CREATEREQUEST.fields_by_name['locale'].message_type = _LOCALE
 _CREATERESPONSE.fields_by_name['locale'].message_type = _LOCALE
 _LISTRESPONSE.fields_by_name['locales'].message_type = _LOCALE
 DESCRIPTOR.message_types_by_name['Locale'] = _LOCALE
@@ -315,8 +302,8 @@ _LOCALES = _descriptor.ServiceDescriptor(
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=398,
-  serialized_end=623,
+  serialized_start=388,
+  serialized_end=613,
   methods=[
   _descriptor.MethodDescriptor(
     name='Create',
diff --git a/perxis/members/members_pb2.py b/perxis/members/members_pb2.py
index 40e8a028ea658f3399cebc8bae2566f74807f90b..265f18aaca0dd3a1aff993ae649e7e1d0c7821a4 100644
--- a/perxis/members/members_pb2.py
+++ b/perxis/members/members_pb2.py
@@ -13,6 +13,7 @@ _sym_db = _symbol_database.Default()
 
 
 from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
+from common import common_pb2 as common_dot_common__pb2
 
 
 DESCRIPTOR = _descriptor.FileDescriptor(
@@ -21,9 +22,9 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=b'Z0github.com/perxteam/perxis/proto/members;members',
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\x15members/members.proto\x12\x0f\x61\x63\x63ount.members\x1a\x1bgoogle/protobuf/empty.proto\"N\n\x06Member\x12\x0e\n\x06org_id\x18\x01 \x01(\t\x12\x0f\n\x07user_id\x18\x02 \x01(\t\x12#\n\x04role\x18\x03 \x01(\x0e\x32\x15.account.members.Role\"R\n\nSetRequest\x12\x0e\n\x06org_id\x18\x01 \x01(\t\x12\x0f\n\x07user_id\x18\x02 \x01(\t\x12#\n\x04role\x18\x03 \x01(\x0e\x32\x15.account.members.Role\"-\n\nGetRequest\x12\x0e\n\x06org_id\x18\x01 \x01(\t\x12\x0f\n\x07user_id\x18\x02 \x01(\t\"2\n\x0bGetResponse\x12#\n\x04role\x18\x03 \x01(\x0e\x32\x15.account.members.Role\"0\n\rRemoveRequest\x12\x0e\n\x06org_id\x18\x01 \x01(\t\x12\x0f\n\x07user_id\x18\x02 \x01(\t\"$\n\x12ListMembersRequest\x12\x0e\n\x06org_id\x18\x01 \x01(\t\"?\n\x13ListMembersResponse\x12(\n\x07members\x18\x01 \x03(\x0b\x32\x17.account.members.Member\"+\n\x18ListOrganizationsRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t\"K\n\x19ListOrganizationsResponse\x12.\n\rorganizations\x18\x01 \x03(\x0b\x32\x17.account.members.Member*8\n\x04Role\x12\x0e\n\nNOT_MEMBER\x10\x00\x12\n\n\x06MEMBER\x10\x01\x12\t\n\x05OWNER\x10\x02\x12\t\n\x05\x41\x44MIN\x10\x03\x32\x99\x03\n\x07Members\x12<\n\x03Set\x12\x1b.account.members.SetRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x42\n\x03Get\x12\x1b.account.members.GetRequest\x1a\x1c.account.members.GetResponse\"\x00\x12\x42\n\x06Remove\x12\x1e.account.members.RemoveRequest\x1a\x16.google.protobuf.Empty\"\x00\x12Z\n\x0bListMembers\x12#.account.members.ListMembersRequest\x1a$.account.members.ListMembersResponse\"\x00\x12l\n\x11ListOrganizations\x12).account.members.ListOrganizationsRequest\x1a*.account.members.ListOrganizationsResponse\"\x00\x42\x32Z0github.com/perxteam/perxis/proto/members;membersb\x06proto3'
+  serialized_pb=b'\n\x15members/members.proto\x12\x0f\x61\x63\x63ount.members\x1a\x1bgoogle/protobuf/empty.proto\x1a\x13\x63ommon/common.proto\"N\n\x06Member\x12\x0e\n\x06org_id\x18\x01 \x01(\t\x12\x0f\n\x07user_id\x18\x02 \x01(\t\x12#\n\x04role\x18\x03 \x01(\x0e\x32\x15.account.members.Role\"R\n\nSetRequest\x12\x0e\n\x06org_id\x18\x01 \x01(\t\x12\x0f\n\x07user_id\x18\x02 \x01(\t\x12#\n\x04role\x18\x03 \x01(\x0e\x32\x15.account.members.Role\"-\n\nGetRequest\x12\x0e\n\x06org_id\x18\x01 \x01(\t\x12\x0f\n\x07user_id\x18\x02 \x01(\t\"2\n\x0bGetResponse\x12#\n\x04role\x18\x03 \x01(\x0e\x32\x15.account.members.Role\"0\n\rRemoveRequest\x12\x0e\n\x06org_id\x18\x01 \x01(\t\x12\x0f\n\x07user_id\x18\x02 \x01(\t\"$\n\x12ListMembersRequest\x12\x0e\n\x06org_id\x18\x01 \x01(\t\"?\n\x13ListMembersResponse\x12(\n\x07members\x18\x01 \x03(\x0b\x32\x17.account.members.Member\"+\n\x18ListOrganizationsRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t\"K\n\x19ListOrganizationsResponse\x12.\n\rorganizations\x18\x01 \x03(\x0b\x32\x17.account.members.Member\"F\n\x18OnCollaboratorSetRequest\x12*\n\x0c\x63ollaborator\x18\x01 \x01(\x0b\x32\x14.common.Collaborator*8\n\x04Role\x12\x0e\n\nNOT_MEMBER\x10\x00\x12\n\n\x06MEMBER\x10\x01\x12\t\n\x05OWNER\x10\x02\x12\t\n\x05\x41\x44MIN\x10\x03\x32\x99\x03\n\x07Members\x12<\n\x03Set\x12\x1b.account.members.SetRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x42\n\x03Get\x12\x1b.account.members.GetRequest\x1a\x1c.account.members.GetResponse\"\x00\x12\x42\n\x06Remove\x12\x1e.account.members.RemoveRequest\x1a\x16.google.protobuf.Empty\"\x00\x12Z\n\x0bListMembers\x12#.account.members.ListMembersRequest\x1a$.account.members.ListMembersResponse\"\x00\x12l\n\x11ListOrganizations\x12).account.members.ListOrganizationsRequest\x1a*.account.members.ListOrganizationsResponse\"\x00\x32\x64\n\x08Observer\x12X\n\x11OnCollaboratorSet\x12).account.members.OnCollaboratorSetRequest\x1a\x16.google.protobuf.Empty\"\x00\x42\x32Z0github.com/perxteam/perxis/proto/members;membersb\x06proto3'
   ,
-  dependencies=[google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,])
+  dependencies=[google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,common_dot_common__pb2.DESCRIPTOR,])
 
 _ROLE = _descriptor.EnumDescriptor(
   name='Role',
@@ -55,8 +56,8 @@ _ROLE = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=609,
-  serialized_end=665,
+  serialized_start=702,
+  serialized_end=758,
 )
 _sym_db.RegisterEnumDescriptor(_ROLE)
 
@@ -109,8 +110,8 @@ _MEMBER = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=71,
-  serialized_end=149,
+  serialized_start=92,
+  serialized_end=170,
 )
 
 
@@ -155,8 +156,8 @@ _SETREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=151,
-  serialized_end=233,
+  serialized_start=172,
+  serialized_end=254,
 )
 
 
@@ -194,8 +195,8 @@ _GETREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=235,
-  serialized_end=280,
+  serialized_start=256,
+  serialized_end=301,
 )
 
 
@@ -226,8 +227,8 @@ _GETRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=282,
-  serialized_end=332,
+  serialized_start=303,
+  serialized_end=353,
 )
 
 
@@ -265,8 +266,8 @@ _REMOVEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=334,
-  serialized_end=382,
+  serialized_start=355,
+  serialized_end=403,
 )
 
 
@@ -297,8 +298,8 @@ _LISTMEMBERSREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=384,
-  serialized_end=420,
+  serialized_start=405,
+  serialized_end=441,
 )
 
 
@@ -329,8 +330,8 @@ _LISTMEMBERSRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=422,
-  serialized_end=485,
+  serialized_start=443,
+  serialized_end=506,
 )
 
 
@@ -361,8 +362,8 @@ _LISTORGANIZATIONSREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=487,
-  serialized_end=530,
+  serialized_start=508,
+  serialized_end=551,
 )
 
 
@@ -393,8 +394,40 @@ _LISTORGANIZATIONSRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=532,
-  serialized_end=607,
+  serialized_start=553,
+  serialized_end=628,
+)
+
+
+_ONCOLLABORATORSETREQUEST = _descriptor.Descriptor(
+  name='OnCollaboratorSetRequest',
+  full_name='account.members.OnCollaboratorSetRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='collaborator', full_name='account.members.OnCollaboratorSetRequest.collaborator', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=630,
+  serialized_end=700,
 )
 
 _MEMBER.fields_by_name['role'].enum_type = _ROLE
@@ -402,6 +435,7 @@ _SETREQUEST.fields_by_name['role'].enum_type = _ROLE
 _GETRESPONSE.fields_by_name['role'].enum_type = _ROLE
 _LISTMEMBERSRESPONSE.fields_by_name['members'].message_type = _MEMBER
 _LISTORGANIZATIONSRESPONSE.fields_by_name['organizations'].message_type = _MEMBER
+_ONCOLLABORATORSETREQUEST.fields_by_name['collaborator'].message_type = common_dot_common__pb2._COLLABORATOR
 DESCRIPTOR.message_types_by_name['Member'] = _MEMBER
 DESCRIPTOR.message_types_by_name['SetRequest'] = _SETREQUEST
 DESCRIPTOR.message_types_by_name['GetRequest'] = _GETREQUEST
@@ -411,6 +445,7 @@ DESCRIPTOR.message_types_by_name['ListMembersRequest'] = _LISTMEMBERSREQUEST
 DESCRIPTOR.message_types_by_name['ListMembersResponse'] = _LISTMEMBERSRESPONSE
 DESCRIPTOR.message_types_by_name['ListOrganizationsRequest'] = _LISTORGANIZATIONSREQUEST
 DESCRIPTOR.message_types_by_name['ListOrganizationsResponse'] = _LISTORGANIZATIONSRESPONSE
+DESCRIPTOR.message_types_by_name['OnCollaboratorSetRequest'] = _ONCOLLABORATORSETREQUEST
 DESCRIPTOR.enum_types_by_name['Role'] = _ROLE
 _sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
@@ -477,6 +512,13 @@ ListOrganizationsResponse = _reflection.GeneratedProtocolMessageType('ListOrgani
   })
 _sym_db.RegisterMessage(ListOrganizationsResponse)
 
+OnCollaboratorSetRequest = _reflection.GeneratedProtocolMessageType('OnCollaboratorSetRequest', (_message.Message,), {
+  'DESCRIPTOR' : _ONCOLLABORATORSETREQUEST,
+  '__module__' : 'members.members_pb2'
+  # @@protoc_insertion_point(class_scope:account.members.OnCollaboratorSetRequest)
+  })
+_sym_db.RegisterMessage(OnCollaboratorSetRequest)
+
 
 DESCRIPTOR._options = None
 
@@ -487,8 +529,8 @@ _MEMBERS = _descriptor.ServiceDescriptor(
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=668,
-  serialized_end=1077,
+  serialized_start=761,
+  serialized_end=1170,
   methods=[
   _descriptor.MethodDescriptor(
     name='Set',
@@ -545,4 +587,30 @@ _sym_db.RegisterServiceDescriptor(_MEMBERS)
 
 DESCRIPTOR.services_by_name['Members'] = _MEMBERS
 
+
+_OBSERVER = _descriptor.ServiceDescriptor(
+  name='Observer',
+  full_name='account.members.Observer',
+  file=DESCRIPTOR,
+  index=1,
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_start=1172,
+  serialized_end=1272,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='OnCollaboratorSet',
+    full_name='account.members.Observer.OnCollaboratorSet',
+    index=0,
+    containing_service=None,
+    input_type=_ONCOLLABORATORSETREQUEST,
+    output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_OBSERVER)
+
+DESCRIPTOR.services_by_name['Observer'] = _OBSERVER
+
 # @@protoc_insertion_point(module_scope)
diff --git a/perxis/members/members_pb2_grpc.py b/perxis/members/members_pb2_grpc.py
index bf86ff4a24fb09be6429217d2643b7767ae6bd40..c535b4079fa6a5101dc30a117d1ee670512b8d5d 100644
--- a/perxis/members/members_pb2_grpc.py
+++ b/perxis/members/members_pb2_grpc.py
@@ -197,3 +197,64 @@ class Members(object):
             members_dot_members__pb2.ListOrganizationsResponse.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+
+class ObserverStub(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def __init__(self, channel):
+        """Constructor.
+
+        Args:
+            channel: A grpc.Channel.
+        """
+        self.OnCollaboratorSet = channel.unary_unary(
+                '/account.members.Observer/OnCollaboratorSet',
+                request_serializer=members_dot_members__pb2.OnCollaboratorSetRequest.SerializeToString,
+                response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+                )
+
+
+class ObserverServicer(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def OnCollaboratorSet(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+
+def add_ObserverServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+            'OnCollaboratorSet': grpc.unary_unary_rpc_method_handler(
+                    servicer.OnCollaboratorSet,
+                    request_deserializer=members_dot_members__pb2.OnCollaboratorSetRequest.FromString,
+                    response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
+            ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+            'account.members.Observer', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+ # This class is part of an EXPERIMENTAL API.
+class Observer(object):
+    """Missing associated documentation comment in .proto file."""
+
+    @staticmethod
+    def OnCollaboratorSet(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/account.members.Observer/OnCollaboratorSet',
+            members_dot_members__pb2.OnCollaboratorSetRequest.SerializeToString,
+            google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/perxis/organizations/organizations_pb2.py b/perxis/organizations/organizations_pb2.py
index 714a957655e4f26f84834f54adb42cad0f7c0e57..a2cad514c8ced1db82b219849b0e2fcc326753b1 100644
--- a/perxis/organizations/organizations_pb2.py
+++ b/perxis/organizations/organizations_pb2.py
@@ -21,7 +21,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=b'Z<github.com/perxteam/perxis/proto/organizations;organizations',
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n!organizations/organizations.proto\x12\x15\x61\x63\x63ount.organizations\x1a\x1bgoogle/protobuf/empty.proto\x1a\x13\x63ommon/common.proto\"O\n\x0cOrganization\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12\x10\n\x08logo_url\x18\x05 \x01(\t\"V\n\rCreateRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x10\n\x08logo_url\x18\x03 \x01(\t\x12\x10\n\x08owner_id\x18\x04 \x01(\t\"B\n\x0e\x43reateResponse\x12\x30\n\x03org\x18\x01 \x01(\x0b\x32#.account.organizations.Organization\"\x1c\n\nGetRequest\x12\x0e\n\x06org_id\x18\x01 \x01(\t\"?\n\x0bGetResponse\x12\x30\n\x03org\x18\x01 \x01(\x0b\x32#.account.organizations.Organization\"T\n\rUpdateRequest\x12\x0e\n\x06org_id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12\x10\n\x08logo_url\x18\x04 \x01(\t\"\x1f\n\rDeleteRequest\x12\x0e\n\x06org_id\x18\x01 \x01(\t\"$\n\x06\x46ilter\x12\x0b\n\x03ids\x18\x03 \x03(\t\x12\r\n\x05names\x18\x04 \x03(\t\"_\n\x0b\x46indRequest\x12-\n\x06\x66ilter\x18\x01 \x01(\x0b\x32\x1d.account.organizations.Filter\x12!\n\x04opts\x18\x02 \x01(\x0b\x32\x13.common.FindOptions\"P\n\x0c\x46indResponse\x12\x31\n\x04orgs\x18\x01 \x03(\x0b\x32#.account.organizations.Organization\x12\r\n\x05total\x18\x02 \x01(\x03\x32\x9f\x03\n\rOrganizations\x12W\n\x06\x43reate\x12$.account.organizations.CreateRequest\x1a%.account.organizations.CreateResponse\"\x00\x12N\n\x03Get\x12!.account.organizations.GetRequest\x1a\".account.organizations.GetResponse\"\x00\x12H\n\x06\x44\x65lete\x12$.account.organizations.DeleteRequest\x1a\x16.google.protobuf.Empty\"\x00\x12Q\n\x04\x46ind\x12\".account.organizations.FindRequest\x1a#.account.organizations.FindResponse\"\x00\x12H\n\x06Update\x12$.account.organizations.UpdateRequest\x1a\x16.google.protobuf.Empty\"\x00\x42>Z<github.com/perxteam/perxis/proto/organizations;organizationsb\x06proto3'
+  serialized_pb=b'\n!organizations/organizations.proto\x12\x15\x61\x63\x63ount.organizations\x1a\x1bgoogle/protobuf/empty.proto\x1a\x13\x63ommon/common.proto\"s\n\x0cOrganization\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12\x10\n\x08logo_url\x18\x05 \x01(\t\x12\x15\n\x08owner_id\x18\x06 \x01(\tH\x00\x88\x01\x01\x42\x0b\n\t_owner_id\"A\n\rCreateRequest\x12\x30\n\x03org\x18\x01 \x01(\x0b\x32#.account.organizations.Organization\"F\n\x0e\x43reateResponse\x12\x34\n\x07\x63reated\x18\x01 \x01(\x0b\x32#.account.organizations.Organization\"\x1c\n\nGetRequest\x12\x0e\n\x06org_id\x18\x01 \x01(\t\"?\n\x0bGetResponse\x12\x30\n\x03org\x18\x01 \x01(\x0b\x32#.account.organizations.Organization\"A\n\rUpdateRequest\x12\x30\n\x03org\x18\x01 \x01(\x0b\x32#.account.organizations.Organization\"\x1f\n\rDeleteRequest\x12\x0e\n\x06org_id\x18\x01 \x01(\t\"$\n\x06\x46ilter\x12\x0b\n\x03ids\x18\x03 \x03(\t\x12\r\n\x05names\x18\x04 \x03(\t\"_\n\x0b\x46indRequest\x12-\n\x06\x66ilter\x18\x01 \x01(\x0b\x32\x1d.account.organizations.Filter\x12!\n\x04opts\x18\x02 \x01(\x0b\x32\x13.common.FindOptions\"P\n\x0c\x46indResponse\x12\x31\n\x04orgs\x18\x01 \x03(\x0b\x32#.account.organizations.Organization\x12\r\n\x05total\x18\x02 \x01(\x03\x32\x9f\x03\n\rOrganizations\x12W\n\x06\x43reate\x12$.account.organizations.CreateRequest\x1a%.account.organizations.CreateResponse\"\x00\x12N\n\x03Get\x12!.account.organizations.GetRequest\x1a\".account.organizations.GetResponse\"\x00\x12H\n\x06\x44\x65lete\x12$.account.organizations.DeleteRequest\x1a\x16.google.protobuf.Empty\"\x00\x12Q\n\x04\x46ind\x12\".account.organizations.FindRequest\x1a#.account.organizations.FindResponse\"\x00\x12H\n\x06Update\x12$.account.organizations.UpdateRequest\x1a\x16.google.protobuf.Empty\"\x00\x42>Z<github.com/perxteam/perxis/proto/organizations;organizationsb\x06proto3'
   ,
   dependencies=[google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,common_dot_common__pb2.DESCRIPTOR,])
 
@@ -64,6 +64,13 @@ _ORGANIZATION = _descriptor.Descriptor(
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='owner_id', full_name='account.organizations.Organization.owner_id', index=4,
+      number=6, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
   ],
   extensions=[
   ],
@@ -75,9 +82,14 @@ _ORGANIZATION = _descriptor.Descriptor(
   syntax='proto3',
   extension_ranges=[],
   oneofs=[
+    _descriptor.OneofDescriptor(
+      name='_owner_id', full_name='account.organizations.Organization._owner_id',
+      index=0, containing_type=None,
+      create_key=_descriptor._internal_create_key,
+    fields=[]),
   ],
   serialized_start=110,
-  serialized_end=189,
+  serialized_end=225,
 )
 
 
@@ -90,30 +102,9 @@ _CREATEREQUEST = _descriptor.Descriptor(
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='name', full_name='account.organizations.CreateRequest.name', index=0,
-      number=1, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='description', full_name='account.organizations.CreateRequest.description', index=1,
-      number=2, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='logo_url', full_name='account.organizations.CreateRequest.logo_url', index=2,
-      number=3, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='owner_id', full_name='account.organizations.CreateRequest.owner_id', index=3,
-      number=4, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
+      name='org', full_name='account.organizations.CreateRequest.org', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
@@ -129,8 +120,8 @@ _CREATEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=191,
-  serialized_end=277,
+  serialized_start=227,
+  serialized_end=292,
 )
 
 
@@ -143,7 +134,7 @@ _CREATERESPONSE = _descriptor.Descriptor(
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='org', full_name='account.organizations.CreateResponse.org', index=0,
+      name='created', full_name='account.organizations.CreateResponse.created', index=0,
       number=1, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
@@ -161,8 +152,8 @@ _CREATERESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=279,
-  serialized_end=345,
+  serialized_start=294,
+  serialized_end=364,
 )
 
 
@@ -193,8 +184,8 @@ _GETREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=347,
-  serialized_end=375,
+  serialized_start=366,
+  serialized_end=394,
 )
 
 
@@ -225,8 +216,8 @@ _GETRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=377,
-  serialized_end=440,
+  serialized_start=396,
+  serialized_end=459,
 )
 
 
@@ -239,30 +230,9 @@ _UPDATEREQUEST = _descriptor.Descriptor(
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='org_id', full_name='account.organizations.UpdateRequest.org_id', index=0,
-      number=1, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='name', full_name='account.organizations.UpdateRequest.name', index=1,
-      number=2, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='description', full_name='account.organizations.UpdateRequest.description', index=2,
-      number=3, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='logo_url', full_name='account.organizations.UpdateRequest.logo_url', index=3,
-      number=4, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
+      name='org', full_name='account.organizations.UpdateRequest.org', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
@@ -278,7 +248,7 @@ _UPDATEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=442,
+  serialized_start=461,
   serialized_end=526,
 )
 
@@ -431,8 +401,13 @@ _FINDRESPONSE = _descriptor.Descriptor(
   serialized_end=776,
 )
 
-_CREATERESPONSE.fields_by_name['org'].message_type = _ORGANIZATION
+_ORGANIZATION.oneofs_by_name['_owner_id'].fields.append(
+  _ORGANIZATION.fields_by_name['owner_id'])
+_ORGANIZATION.fields_by_name['owner_id'].containing_oneof = _ORGANIZATION.oneofs_by_name['_owner_id']
+_CREATEREQUEST.fields_by_name['org'].message_type = _ORGANIZATION
+_CREATERESPONSE.fields_by_name['created'].message_type = _ORGANIZATION
 _GETRESPONSE.fields_by_name['org'].message_type = _ORGANIZATION
+_UPDATEREQUEST.fields_by_name['org'].message_type = _ORGANIZATION
 _FINDREQUEST.fields_by_name['filter'].message_type = _FILTER
 _FINDREQUEST.fields_by_name['opts'].message_type = common_dot_common__pb2._FINDOPTIONS
 _FINDRESPONSE.fields_by_name['orgs'].message_type = _ORGANIZATION
diff --git a/perxis/roles/roles_pb2.py b/perxis/roles/roles_pb2.py
new file mode 100644
index 0000000000000000000000000000000000000000..7dae3e8fbe9ec2870c91eafc3d2585acbe814851
--- /dev/null
+++ b/perxis/roles/roles_pb2.py
@@ -0,0 +1,637 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: roles/roles.proto
+"""Generated protocol buffer code."""
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
+from common import common_pb2 as common_dot_common__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='roles/roles.proto',
+  package='content.roles',
+  syntax='proto3',
+  serialized_options=b'Z,github.com/perxteam/perxis/proto/roles;roles',
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\x11roles/roles.proto\x12\rcontent.roles\x1a\x1bgoogle/protobuf/empty.proto\x1a\x13\x63ommon/common.proto\"d\n\x04Role\x12\n\n\x02id\x18\x01 \x01(\t\x12\x10\n\x08space_id\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x04 \x01(\t\x12\x1b\n\x05rules\x18\x05 \x03(\x0b\x32\x0c.common.Rule\"2\n\rCreateRequest\x12!\n\x04role\x18\x01 \x01(\x0b\x32\x13.content.roles.Role\"6\n\x0e\x43reateResponse\x12$\n\x07\x63reated\x18\x01 \x01(\x0b\x32\x13.content.roles.Role\"/\n\nGetRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0f\n\x07role_id\x18\x02 \x01(\t\"0\n\x0bGetResponse\x12!\n\x04role\x18\x01 \x01(\x0b\x32\x13.content.roles.Role\"2\n\rUpdateRequest\x12!\n\x04role\x18\x01 \x01(\x0b\x32\x13.content.roles.Role\"\x1f\n\x0bListRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\"2\n\x0cListResponse\x12\"\n\x05roles\x18\x01 \x03(\x0b\x32\x13.content.roles.Role\"2\n\rDeleteRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0f\n\x07role_id\x18\x02 \x01(\t\"O\n\x0eSetRuleRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0f\n\x07role_id\x18\x02 \x01(\t\x12\x1a\n\x04rule\x18\x03 \x01(\x0b\x32\x0c.common.Rule\"G\n\x11RemoveRuleRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0f\n\x07role_id\x18\x02 \x01(\t\x12\x0f\n\x07rule_id\x18\x03 \x01(\t2\xe5\x03\n\x05Roles\x12G\n\x06\x43reate\x12\x1c.content.roles.CreateRequest\x1a\x1d.content.roles.CreateResponse\"\x00\x12>\n\x03Get\x12\x19.content.roles.GetRequest\x1a\x1a.content.roles.GetResponse\"\x00\x12@\n\x06Update\x12\x1c.content.roles.UpdateRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x41\n\x04List\x12\x1a.content.roles.ListRequest\x1a\x1b.content.roles.ListResponse\"\x00\x12@\n\x06\x44\x65lete\x12\x1c.content.roles.DeleteRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x42\n\x07SetRule\x12\x1d.content.roles.SetRuleRequest\x1a\x16.google.protobuf.Empty\"\x00\x12H\n\nRemoveRule\x12 .content.roles.RemoveRuleRequest\x1a\x16.google.protobuf.Empty\"\x00\x42.Z,github.com/perxteam/perxis/proto/roles;rolesb\x06proto3'
+  ,
+  dependencies=[google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,common_dot_common__pb2.DESCRIPTOR,])
+
+
+
+
+_ROLE = _descriptor.Descriptor(
+  name='Role',
+  full_name='content.roles.Role',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='id', full_name='content.roles.Role.id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='space_id', full_name='content.roles.Role.space_id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='name', full_name='content.roles.Role.name', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='description', full_name='content.roles.Role.description', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='rules', full_name='content.roles.Role.rules', index=4,
+      number=5, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=86,
+  serialized_end=186,
+)
+
+
+_CREATEREQUEST = _descriptor.Descriptor(
+  name='CreateRequest',
+  full_name='content.roles.CreateRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='role', full_name='content.roles.CreateRequest.role', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=188,
+  serialized_end=238,
+)
+
+
+_CREATERESPONSE = _descriptor.Descriptor(
+  name='CreateResponse',
+  full_name='content.roles.CreateResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='created', full_name='content.roles.CreateResponse.created', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=240,
+  serialized_end=294,
+)
+
+
+_GETREQUEST = _descriptor.Descriptor(
+  name='GetRequest',
+  full_name='content.roles.GetRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='space_id', full_name='content.roles.GetRequest.space_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='role_id', full_name='content.roles.GetRequest.role_id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=296,
+  serialized_end=343,
+)
+
+
+_GETRESPONSE = _descriptor.Descriptor(
+  name='GetResponse',
+  full_name='content.roles.GetResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='role', full_name='content.roles.GetResponse.role', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=345,
+  serialized_end=393,
+)
+
+
+_UPDATEREQUEST = _descriptor.Descriptor(
+  name='UpdateRequest',
+  full_name='content.roles.UpdateRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='role', full_name='content.roles.UpdateRequest.role', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=395,
+  serialized_end=445,
+)
+
+
+_LISTREQUEST = _descriptor.Descriptor(
+  name='ListRequest',
+  full_name='content.roles.ListRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='space_id', full_name='content.roles.ListRequest.space_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=447,
+  serialized_end=478,
+)
+
+
+_LISTRESPONSE = _descriptor.Descriptor(
+  name='ListResponse',
+  full_name='content.roles.ListResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='roles', full_name='content.roles.ListResponse.roles', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=480,
+  serialized_end=530,
+)
+
+
+_DELETEREQUEST = _descriptor.Descriptor(
+  name='DeleteRequest',
+  full_name='content.roles.DeleteRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='space_id', full_name='content.roles.DeleteRequest.space_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='role_id', full_name='content.roles.DeleteRequest.role_id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=532,
+  serialized_end=582,
+)
+
+
+_SETRULEREQUEST = _descriptor.Descriptor(
+  name='SetRuleRequest',
+  full_name='content.roles.SetRuleRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='space_id', full_name='content.roles.SetRuleRequest.space_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='role_id', full_name='content.roles.SetRuleRequest.role_id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='rule', full_name='content.roles.SetRuleRequest.rule', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=584,
+  serialized_end=663,
+)
+
+
+_REMOVERULEREQUEST = _descriptor.Descriptor(
+  name='RemoveRuleRequest',
+  full_name='content.roles.RemoveRuleRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='space_id', full_name='content.roles.RemoveRuleRequest.space_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='role_id', full_name='content.roles.RemoveRuleRequest.role_id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='rule_id', full_name='content.roles.RemoveRuleRequest.rule_id', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=665,
+  serialized_end=736,
+)
+
+_ROLE.fields_by_name['rules'].message_type = common_dot_common__pb2._RULE
+_CREATEREQUEST.fields_by_name['role'].message_type = _ROLE
+_CREATERESPONSE.fields_by_name['created'].message_type = _ROLE
+_GETRESPONSE.fields_by_name['role'].message_type = _ROLE
+_UPDATEREQUEST.fields_by_name['role'].message_type = _ROLE
+_LISTRESPONSE.fields_by_name['roles'].message_type = _ROLE
+_SETRULEREQUEST.fields_by_name['rule'].message_type = common_dot_common__pb2._RULE
+DESCRIPTOR.message_types_by_name['Role'] = _ROLE
+DESCRIPTOR.message_types_by_name['CreateRequest'] = _CREATEREQUEST
+DESCRIPTOR.message_types_by_name['CreateResponse'] = _CREATERESPONSE
+DESCRIPTOR.message_types_by_name['GetRequest'] = _GETREQUEST
+DESCRIPTOR.message_types_by_name['GetResponse'] = _GETRESPONSE
+DESCRIPTOR.message_types_by_name['UpdateRequest'] = _UPDATEREQUEST
+DESCRIPTOR.message_types_by_name['ListRequest'] = _LISTREQUEST
+DESCRIPTOR.message_types_by_name['ListResponse'] = _LISTRESPONSE
+DESCRIPTOR.message_types_by_name['DeleteRequest'] = _DELETEREQUEST
+DESCRIPTOR.message_types_by_name['SetRuleRequest'] = _SETRULEREQUEST
+DESCRIPTOR.message_types_by_name['RemoveRuleRequest'] = _REMOVERULEREQUEST
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+Role = _reflection.GeneratedProtocolMessageType('Role', (_message.Message,), {
+  'DESCRIPTOR' : _ROLE,
+  '__module__' : 'roles.roles_pb2'
+  # @@protoc_insertion_point(class_scope:content.roles.Role)
+  })
+_sym_db.RegisterMessage(Role)
+
+CreateRequest = _reflection.GeneratedProtocolMessageType('CreateRequest', (_message.Message,), {
+  'DESCRIPTOR' : _CREATEREQUEST,
+  '__module__' : 'roles.roles_pb2'
+  # @@protoc_insertion_point(class_scope:content.roles.CreateRequest)
+  })
+_sym_db.RegisterMessage(CreateRequest)
+
+CreateResponse = _reflection.GeneratedProtocolMessageType('CreateResponse', (_message.Message,), {
+  'DESCRIPTOR' : _CREATERESPONSE,
+  '__module__' : 'roles.roles_pb2'
+  # @@protoc_insertion_point(class_scope:content.roles.CreateResponse)
+  })
+_sym_db.RegisterMessage(CreateResponse)
+
+GetRequest = _reflection.GeneratedProtocolMessageType('GetRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETREQUEST,
+  '__module__' : 'roles.roles_pb2'
+  # @@protoc_insertion_point(class_scope:content.roles.GetRequest)
+  })
+_sym_db.RegisterMessage(GetRequest)
+
+GetResponse = _reflection.GeneratedProtocolMessageType('GetResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GETRESPONSE,
+  '__module__' : 'roles.roles_pb2'
+  # @@protoc_insertion_point(class_scope:content.roles.GetResponse)
+  })
+_sym_db.RegisterMessage(GetResponse)
+
+UpdateRequest = _reflection.GeneratedProtocolMessageType('UpdateRequest', (_message.Message,), {
+  'DESCRIPTOR' : _UPDATEREQUEST,
+  '__module__' : 'roles.roles_pb2'
+  # @@protoc_insertion_point(class_scope:content.roles.UpdateRequest)
+  })
+_sym_db.RegisterMessage(UpdateRequest)
+
+ListRequest = _reflection.GeneratedProtocolMessageType('ListRequest', (_message.Message,), {
+  'DESCRIPTOR' : _LISTREQUEST,
+  '__module__' : 'roles.roles_pb2'
+  # @@protoc_insertion_point(class_scope:content.roles.ListRequest)
+  })
+_sym_db.RegisterMessage(ListRequest)
+
+ListResponse = _reflection.GeneratedProtocolMessageType('ListResponse', (_message.Message,), {
+  'DESCRIPTOR' : _LISTRESPONSE,
+  '__module__' : 'roles.roles_pb2'
+  # @@protoc_insertion_point(class_scope:content.roles.ListResponse)
+  })
+_sym_db.RegisterMessage(ListResponse)
+
+DeleteRequest = _reflection.GeneratedProtocolMessageType('DeleteRequest', (_message.Message,), {
+  'DESCRIPTOR' : _DELETEREQUEST,
+  '__module__' : 'roles.roles_pb2'
+  # @@protoc_insertion_point(class_scope:content.roles.DeleteRequest)
+  })
+_sym_db.RegisterMessage(DeleteRequest)
+
+SetRuleRequest = _reflection.GeneratedProtocolMessageType('SetRuleRequest', (_message.Message,), {
+  'DESCRIPTOR' : _SETRULEREQUEST,
+  '__module__' : 'roles.roles_pb2'
+  # @@protoc_insertion_point(class_scope:content.roles.SetRuleRequest)
+  })
+_sym_db.RegisterMessage(SetRuleRequest)
+
+RemoveRuleRequest = _reflection.GeneratedProtocolMessageType('RemoveRuleRequest', (_message.Message,), {
+  'DESCRIPTOR' : _REMOVERULEREQUEST,
+  '__module__' : 'roles.roles_pb2'
+  # @@protoc_insertion_point(class_scope:content.roles.RemoveRuleRequest)
+  })
+_sym_db.RegisterMessage(RemoveRuleRequest)
+
+
+DESCRIPTOR._options = None
+
+_ROLES = _descriptor.ServiceDescriptor(
+  name='Roles',
+  full_name='content.roles.Roles',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_start=739,
+  serialized_end=1224,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='Create',
+    full_name='content.roles.Roles.Create',
+    index=0,
+    containing_service=None,
+    input_type=_CREATEREQUEST,
+    output_type=_CREATERESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='Get',
+    full_name='content.roles.Roles.Get',
+    index=1,
+    containing_service=None,
+    input_type=_GETREQUEST,
+    output_type=_GETRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='Update',
+    full_name='content.roles.Roles.Update',
+    index=2,
+    containing_service=None,
+    input_type=_UPDATEREQUEST,
+    output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='List',
+    full_name='content.roles.Roles.List',
+    index=3,
+    containing_service=None,
+    input_type=_LISTREQUEST,
+    output_type=_LISTRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='Delete',
+    full_name='content.roles.Roles.Delete',
+    index=4,
+    containing_service=None,
+    input_type=_DELETEREQUEST,
+    output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetRule',
+    full_name='content.roles.Roles.SetRule',
+    index=5,
+    containing_service=None,
+    input_type=_SETRULEREQUEST,
+    output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveRule',
+    full_name='content.roles.Roles.RemoveRule',
+    index=6,
+    containing_service=None,
+    input_type=_REMOVERULEREQUEST,
+    output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_ROLES)
+
+DESCRIPTOR.services_by_name['Roles'] = _ROLES
+
+# @@protoc_insertion_point(module_scope)
diff --git a/perxis/roles/roles_pb2_grpc.py b/perxis/roles/roles_pb2_grpc.py
new file mode 100644
index 0000000000000000000000000000000000000000..e5632b40f6ae5cad17b536121d678861ad01cf8c
--- /dev/null
+++ b/perxis/roles/roles_pb2_grpc.py
@@ -0,0 +1,272 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+"""Client and server classes corresponding to protobuf-defined services."""
+import grpc
+
+from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
+from roles import roles_pb2 as roles_dot_roles__pb2
+
+
+class RolesStub(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def __init__(self, channel):
+        """Constructor.
+
+        Args:
+            channel: A grpc.Channel.
+        """
+        self.Create = channel.unary_unary(
+                '/content.roles.Roles/Create',
+                request_serializer=roles_dot_roles__pb2.CreateRequest.SerializeToString,
+                response_deserializer=roles_dot_roles__pb2.CreateResponse.FromString,
+                )
+        self.Get = channel.unary_unary(
+                '/content.roles.Roles/Get',
+                request_serializer=roles_dot_roles__pb2.GetRequest.SerializeToString,
+                response_deserializer=roles_dot_roles__pb2.GetResponse.FromString,
+                )
+        self.Update = channel.unary_unary(
+                '/content.roles.Roles/Update',
+                request_serializer=roles_dot_roles__pb2.UpdateRequest.SerializeToString,
+                response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+                )
+        self.List = channel.unary_unary(
+                '/content.roles.Roles/List',
+                request_serializer=roles_dot_roles__pb2.ListRequest.SerializeToString,
+                response_deserializer=roles_dot_roles__pb2.ListResponse.FromString,
+                )
+        self.Delete = channel.unary_unary(
+                '/content.roles.Roles/Delete',
+                request_serializer=roles_dot_roles__pb2.DeleteRequest.SerializeToString,
+                response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+                )
+        self.SetRule = channel.unary_unary(
+                '/content.roles.Roles/SetRule',
+                request_serializer=roles_dot_roles__pb2.SetRuleRequest.SerializeToString,
+                response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+                )
+        self.RemoveRule = channel.unary_unary(
+                '/content.roles.Roles/RemoveRule',
+                request_serializer=roles_dot_roles__pb2.RemoveRuleRequest.SerializeToString,
+                response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+                )
+
+
+class RolesServicer(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def Create(self, request, context):
+        """Create - создает роль в рамках пространства
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def Get(self, request, context):
+        """Get - возвращает роль по id
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def Update(self, request, context):
+        """Update - обновляет параметры роли
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def List(self, request, context):
+        """List - возвращает список ролей, созданных в пространстве
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def Delete(self, request, context):
+        """Delete - удаляет указанную роль из пространстве
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def SetRule(self, request, context):
+        """SetRule - добавляет правило доступа к API для роли
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def RemoveRule(self, request, context):
+        """RemoveRule - удаляет правило для роли
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+
+def add_RolesServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+            'Create': grpc.unary_unary_rpc_method_handler(
+                    servicer.Create,
+                    request_deserializer=roles_dot_roles__pb2.CreateRequest.FromString,
+                    response_serializer=roles_dot_roles__pb2.CreateResponse.SerializeToString,
+            ),
+            'Get': grpc.unary_unary_rpc_method_handler(
+                    servicer.Get,
+                    request_deserializer=roles_dot_roles__pb2.GetRequest.FromString,
+                    response_serializer=roles_dot_roles__pb2.GetResponse.SerializeToString,
+            ),
+            'Update': grpc.unary_unary_rpc_method_handler(
+                    servicer.Update,
+                    request_deserializer=roles_dot_roles__pb2.UpdateRequest.FromString,
+                    response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
+            ),
+            'List': grpc.unary_unary_rpc_method_handler(
+                    servicer.List,
+                    request_deserializer=roles_dot_roles__pb2.ListRequest.FromString,
+                    response_serializer=roles_dot_roles__pb2.ListResponse.SerializeToString,
+            ),
+            'Delete': grpc.unary_unary_rpc_method_handler(
+                    servicer.Delete,
+                    request_deserializer=roles_dot_roles__pb2.DeleteRequest.FromString,
+                    response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
+            ),
+            'SetRule': grpc.unary_unary_rpc_method_handler(
+                    servicer.SetRule,
+                    request_deserializer=roles_dot_roles__pb2.SetRuleRequest.FromString,
+                    response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
+            ),
+            'RemoveRule': grpc.unary_unary_rpc_method_handler(
+                    servicer.RemoveRule,
+                    request_deserializer=roles_dot_roles__pb2.RemoveRuleRequest.FromString,
+                    response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
+            ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+            'content.roles.Roles', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+ # This class is part of an EXPERIMENTAL API.
+class Roles(object):
+    """Missing associated documentation comment in .proto file."""
+
+    @staticmethod
+    def Create(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.roles.Roles/Create',
+            roles_dot_roles__pb2.CreateRequest.SerializeToString,
+            roles_dot_roles__pb2.CreateResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def Get(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.roles.Roles/Get',
+            roles_dot_roles__pb2.GetRequest.SerializeToString,
+            roles_dot_roles__pb2.GetResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def Update(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.roles.Roles/Update',
+            roles_dot_roles__pb2.UpdateRequest.SerializeToString,
+            google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def List(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.roles.Roles/List',
+            roles_dot_roles__pb2.ListRequest.SerializeToString,
+            roles_dot_roles__pb2.ListResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def Delete(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.roles.Roles/Delete',
+            roles_dot_roles__pb2.DeleteRequest.SerializeToString,
+            google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def SetRule(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.roles.Roles/SetRule',
+            roles_dot_roles__pb2.SetRuleRequest.SerializeToString,
+            google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def RemoveRule(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.roles.Roles/RemoveRule',
+            roles_dot_roles__pb2.RemoveRuleRequest.SerializeToString,
+            google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/perxis/spaces/spaces_pb2.py b/perxis/spaces/spaces_pb2.py
index 7d3f9bf378b224ee23923264e6abb59230a6473d..8bb584e06e644419f0b0fcc3d93b30e1d47973f4 100644
--- a/perxis/spaces/spaces_pb2.py
+++ b/perxis/spaces/spaces_pb2.py
@@ -21,7 +21,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=b'Z.github.com/perxteam/perxis/proto/spaces;spaces',
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\x13spaces/spaces.proto\x12\x0e\x63ontent.spaces\x1a\x1bgoogle/protobuf/empty.proto\"\x9d\x01\n\x05Space\x12\n\n\x02id\x18\x01 \x01(\t\x12\x17\n\x0forganization_id\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x04 \x01(\t\x12$\n\x05state\x18\x05 \x01(\x0e\x32\x15.content.spaces.State\x12&\n\x06\x63onfig\x18\n \x01(\x0b\x32\x16.content.spaces.Config\"\x1a\n\x06\x43onfig\x12\x10\n\x08\x66\x65\x61tures\x18\x01 \x03(\t\"j\n\rCreateRequest\x12\x0e\n\x06org_id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12&\n\x06\x63onfig\x18\x05 \x01(\x0b\x32\x16.content.spaces.Config\"6\n\x0e\x43reateResponse\x12$\n\x05space\x18\x01 \x01(\x0b\x32\x15.content.spaces.Space\"\x1e\n\nGetRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\"3\n\x0bGetResponse\x12$\n\x05space\x18\x01 \x01(\x0b\x32\x15.content.spaces.Space\"\x1d\n\x0bListRequest\x12\x0e\n\x06org_id\x18\x01 \x01(\t\"5\n\x0cListResponse\x12%\n\x06spaces\x18\x01 \x03(\x0b\x32\x15.content.spaces.Space\"l\n\rUpdateRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12&\n\x06\x63onfig\x18\x05 \x01(\x0b\x32\x16.content.spaces.Config\"!\n\rDeleteRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t*e\n\x05State\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x07\n\x03NEW\x10\x01\x12\t\n\x05READY\x10\x02\x12\r\n\tPREPARING\x10\x03\x12\x0f\n\x0bMAINTENANCE\x10\x04\x12\r\n\tMIGRATION\x10\x05\x12\x0c\n\x08\x44\x45LETING\x10\x06\x32\xe0\x02\n\x06Spaces\x12I\n\x06\x43reate\x12\x1d.content.spaces.CreateRequest\x1a\x1e.content.spaces.CreateResponse\"\x00\x12@\n\x03Get\x12\x1a.content.spaces.GetRequest\x1a\x1b.content.spaces.GetResponse\"\x00\x12\x43\n\x04List\x12\x1b.content.spaces.ListRequest\x1a\x1c.content.spaces.ListResponse\"\x00\x12\x41\n\x06Update\x12\x1d.content.spaces.UpdateRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x41\n\x06\x44\x65lete\x12\x1d.content.spaces.DeleteRequest\x1a\x16.google.protobuf.Empty\"\x00\x42\x30Z.github.com/perxteam/perxis/proto/spaces;spacesb\x06proto3'
+  serialized_pb=b'\n\x13spaces/spaces.proto\x12\x0e\x63ontent.spaces\x1a\x1bgoogle/protobuf/empty.proto\"\x94\x01\n\x05Space\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0e\n\x06org_id\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x04 \x01(\t\x12$\n\x05state\x18\x05 \x01(\x0e\x32\x15.content.spaces.State\x12&\n\x06\x63onfig\x18\n \x01(\x0b\x32\x16.content.spaces.Config\"\x1a\n\x06\x43onfig\x12\x10\n\x08\x66\x65\x61tures\x18\x01 \x03(\t\"5\n\rCreateRequest\x12$\n\x05space\x18\x01 \x01(\x0b\x32\x15.content.spaces.Space\"8\n\x0e\x43reateResponse\x12&\n\x07\x63reated\x18\x01 \x01(\x0b\x32\x15.content.spaces.Space\"\x1e\n\nGetRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\"3\n\x0bGetResponse\x12$\n\x05space\x18\x01 \x01(\x0b\x32\x15.content.spaces.Space\"\x1d\n\x0bListRequest\x12\x0e\n\x06org_id\x18\x01 \x01(\t\"5\n\x0cListResponse\x12%\n\x06spaces\x18\x01 \x03(\x0b\x32\x15.content.spaces.Space\"5\n\rUpdateRequest\x12$\n\x05space\x18\x01 \x01(\x0b\x32\x15.content.spaces.Space\"O\n\x13UpdateConfigRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12&\n\x06\x63onfig\x18\x02 \x01(\x0b\x32\x16.content.spaces.Config\"!\n\rDeleteRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t*p\n\x05State\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x07\n\x03NEW\x10\x01\x12\t\n\x05READY\x10\x02\x12\r\n\tPREPARING\x10\x03\x12\x0f\n\x0bMAINTENANCE\x10\x04\x12\r\n\tMIGRATION\x10\x05\x12\x0c\n\x08\x44\x45LETING\x10\x06\x12\t\n\x05\x45RROR\x10\x07\x32\xaf\x03\n\x06Spaces\x12I\n\x06\x43reate\x12\x1d.content.spaces.CreateRequest\x1a\x1e.content.spaces.CreateResponse\"\x00\x12@\n\x03Get\x12\x1a.content.spaces.GetRequest\x1a\x1b.content.spaces.GetResponse\"\x00\x12\x43\n\x04List\x12\x1b.content.spaces.ListRequest\x1a\x1c.content.spaces.ListResponse\"\x00\x12\x41\n\x06Update\x12\x1d.content.spaces.UpdateRequest\x1a\x16.google.protobuf.Empty\"\x00\x12M\n\x0cUpdateConfig\x12#.content.spaces.UpdateConfigRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x41\n\x06\x44\x65lete\x12\x1d.content.spaces.DeleteRequest\x1a\x16.google.protobuf.Empty\"\x00\x42\x30Z.github.com/perxteam/perxis/proto/spaces;spacesb\x06proto3'
   ,
   dependencies=[google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,])
 
@@ -67,11 +67,16 @@ _STATE = _descriptor.EnumDescriptor(
       serialized_options=None,
       type=None,
       create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='ERROR', index=7, number=7,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=736,
-  serialized_end=837,
+  serialized_start=702,
+  serialized_end=814,
 )
 _sym_db.RegisterEnumDescriptor(_STATE)
 
@@ -83,6 +88,7 @@ PREPARING = 3
 MAINTENANCE = 4
 MIGRATION = 5
 DELETING = 6
+ERROR = 7
 
 
 
@@ -102,7 +108,7 @@ _SPACE = _descriptor.Descriptor(
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='organization_id', full_name='content.spaces.Space.organization_id', index=1,
+      name='org_id', full_name='content.spaces.Space.org_id', index=1,
       number=2, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
@@ -149,7 +155,7 @@ _SPACE = _descriptor.Descriptor(
   oneofs=[
   ],
   serialized_start=69,
-  serialized_end=226,
+  serialized_end=217,
 )
 
 
@@ -180,8 +186,8 @@ _CONFIG = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=228,
-  serialized_end=254,
+  serialized_start=219,
+  serialized_end=245,
 )
 
 
@@ -194,29 +200,8 @@ _CREATEREQUEST = _descriptor.Descriptor(
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='org_id', full_name='content.spaces.CreateRequest.org_id', index=0,
-      number=1, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='name', full_name='content.spaces.CreateRequest.name', index=1,
-      number=2, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='description', full_name='content.spaces.CreateRequest.description', index=2,
-      number=3, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='config', full_name='content.spaces.CreateRequest.config', index=3,
-      number=5, type=11, cpp_type=10, label=1,
+      name='space', full_name='content.spaces.CreateRequest.space', index=0,
+      number=1, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
@@ -233,8 +218,8 @@ _CREATEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=256,
-  serialized_end=362,
+  serialized_start=247,
+  serialized_end=300,
 )
 
 
@@ -247,7 +232,7 @@ _CREATERESPONSE = _descriptor.Descriptor(
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='space', full_name='content.spaces.CreateResponse.space', index=0,
+      name='created', full_name='content.spaces.CreateResponse.created', index=0,
       number=1, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
@@ -265,8 +250,8 @@ _CREATERESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=364,
-  serialized_end=418,
+  serialized_start=302,
+  serialized_end=358,
 )
 
 
@@ -297,8 +282,8 @@ _GETREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=420,
-  serialized_end=450,
+  serialized_start=360,
+  serialized_end=390,
 )
 
 
@@ -329,8 +314,8 @@ _GETRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=452,
-  serialized_end=503,
+  serialized_start=392,
+  serialized_end=443,
 )
 
 
@@ -361,8 +346,8 @@ _LISTREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=505,
-  serialized_end=534,
+  serialized_start=445,
+  serialized_end=474,
 )
 
 
@@ -393,8 +378,8 @@ _LISTRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=536,
-  serialized_end=589,
+  serialized_start=476,
+  serialized_end=529,
 )
 
 
@@ -407,29 +392,47 @@ _UPDATEREQUEST = _descriptor.Descriptor(
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='space_id', full_name='content.spaces.UpdateRequest.space_id', index=0,
-      number=1, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='name', full_name='content.spaces.UpdateRequest.name', index=1,
-      number=2, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
+      name='space', full_name='content.spaces.UpdateRequest.space', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=531,
+  serialized_end=584,
+)
+
+
+_UPDATECONFIGREQUEST = _descriptor.Descriptor(
+  name='UpdateConfigRequest',
+  full_name='content.spaces.UpdateConfigRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
     _descriptor.FieldDescriptor(
-      name='description', full_name='content.spaces.UpdateRequest.description', index=2,
-      number=3, type=9, cpp_type=9, label=1,
+      name='space_id', full_name='content.spaces.UpdateConfigRequest.space_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='config', full_name='content.spaces.UpdateRequest.config', index=3,
-      number=5, type=11, cpp_type=10, label=1,
+      name='config', full_name='content.spaces.UpdateConfigRequest.config', index=1,
+      number=2, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
@@ -446,8 +449,8 @@ _UPDATEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=591,
-  serialized_end=699,
+  serialized_start=586,
+  serialized_end=665,
 )
 
 
@@ -478,17 +481,18 @@ _DELETEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=701,
-  serialized_end=734,
+  serialized_start=667,
+  serialized_end=700,
 )
 
 _SPACE.fields_by_name['state'].enum_type = _STATE
 _SPACE.fields_by_name['config'].message_type = _CONFIG
-_CREATEREQUEST.fields_by_name['config'].message_type = _CONFIG
-_CREATERESPONSE.fields_by_name['space'].message_type = _SPACE
+_CREATEREQUEST.fields_by_name['space'].message_type = _SPACE
+_CREATERESPONSE.fields_by_name['created'].message_type = _SPACE
 _GETRESPONSE.fields_by_name['space'].message_type = _SPACE
 _LISTRESPONSE.fields_by_name['spaces'].message_type = _SPACE
-_UPDATEREQUEST.fields_by_name['config'].message_type = _CONFIG
+_UPDATEREQUEST.fields_by_name['space'].message_type = _SPACE
+_UPDATECONFIGREQUEST.fields_by_name['config'].message_type = _CONFIG
 DESCRIPTOR.message_types_by_name['Space'] = _SPACE
 DESCRIPTOR.message_types_by_name['Config'] = _CONFIG
 DESCRIPTOR.message_types_by_name['CreateRequest'] = _CREATEREQUEST
@@ -498,6 +502,7 @@ DESCRIPTOR.message_types_by_name['GetResponse'] = _GETRESPONSE
 DESCRIPTOR.message_types_by_name['ListRequest'] = _LISTREQUEST
 DESCRIPTOR.message_types_by_name['ListResponse'] = _LISTRESPONSE
 DESCRIPTOR.message_types_by_name['UpdateRequest'] = _UPDATEREQUEST
+DESCRIPTOR.message_types_by_name['UpdateConfigRequest'] = _UPDATECONFIGREQUEST
 DESCRIPTOR.message_types_by_name['DeleteRequest'] = _DELETEREQUEST
 DESCRIPTOR.enum_types_by_name['State'] = _STATE
 _sym_db.RegisterFileDescriptor(DESCRIPTOR)
@@ -565,6 +570,13 @@ UpdateRequest = _reflection.GeneratedProtocolMessageType('UpdateRequest', (_mess
   })
 _sym_db.RegisterMessage(UpdateRequest)
 
+UpdateConfigRequest = _reflection.GeneratedProtocolMessageType('UpdateConfigRequest', (_message.Message,), {
+  'DESCRIPTOR' : _UPDATECONFIGREQUEST,
+  '__module__' : 'spaces.spaces_pb2'
+  # @@protoc_insertion_point(class_scope:content.spaces.UpdateConfigRequest)
+  })
+_sym_db.RegisterMessage(UpdateConfigRequest)
+
 DeleteRequest = _reflection.GeneratedProtocolMessageType('DeleteRequest', (_message.Message,), {
   'DESCRIPTOR' : _DELETEREQUEST,
   '__module__' : 'spaces.spaces_pb2'
@@ -582,8 +594,8 @@ _SPACES = _descriptor.ServiceDescriptor(
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=840,
-  serialized_end=1192,
+  serialized_start=817,
+  serialized_end=1248,
   methods=[
   _descriptor.MethodDescriptor(
     name='Create',
@@ -625,10 +637,20 @@ _SPACES = _descriptor.ServiceDescriptor(
     serialized_options=None,
     create_key=_descriptor._internal_create_key,
   ),
+  _descriptor.MethodDescriptor(
+    name='UpdateConfig',
+    full_name='content.spaces.Spaces.UpdateConfig',
+    index=4,
+    containing_service=None,
+    input_type=_UPDATECONFIGREQUEST,
+    output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
   _descriptor.MethodDescriptor(
     name='Delete',
     full_name='content.spaces.Spaces.Delete',
-    index=4,
+    index=5,
     containing_service=None,
     input_type=_DELETEREQUEST,
     output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
diff --git a/perxis/spaces/spaces_pb2_grpc.py b/perxis/spaces/spaces_pb2_grpc.py
index 5114fe44780b6d2078b73d0151e95b46f96e56a3..2ab95a7b82f2899207dc7a4ed6c00b3c734db268 100644
--- a/perxis/spaces/spaces_pb2_grpc.py
+++ b/perxis/spaces/spaces_pb2_grpc.py
@@ -35,6 +35,11 @@ class SpacesStub(object):
                 request_serializer=spaces_dot_spaces__pb2.UpdateRequest.SerializeToString,
                 response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
                 )
+        self.UpdateConfig = channel.unary_unary(
+                '/content.spaces.Spaces/UpdateConfig',
+                request_serializer=spaces_dot_spaces__pb2.UpdateConfigRequest.SerializeToString,
+                response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+                )
         self.Delete = channel.unary_unary(
                 '/content.spaces.Spaces/Delete',
                 request_serializer=spaces_dot_spaces__pb2.DeleteRequest.SerializeToString,
@@ -69,6 +74,12 @@ class SpacesServicer(object):
         context.set_details('Method not implemented!')
         raise NotImplementedError('Method not implemented!')
 
+    def UpdateConfig(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
     def Delete(self, request, context):
         """Missing associated documentation comment in .proto file."""
         context.set_code(grpc.StatusCode.UNIMPLEMENTED)
@@ -98,6 +109,11 @@ def add_SpacesServicer_to_server(servicer, server):
                     request_deserializer=spaces_dot_spaces__pb2.UpdateRequest.FromString,
                     response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
             ),
+            'UpdateConfig': grpc.unary_unary_rpc_method_handler(
+                    servicer.UpdateConfig,
+                    request_deserializer=spaces_dot_spaces__pb2.UpdateConfigRequest.FromString,
+                    response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
+            ),
             'Delete': grpc.unary_unary_rpc_method_handler(
                     servicer.Delete,
                     request_deserializer=spaces_dot_spaces__pb2.DeleteRequest.FromString,
@@ -181,6 +197,23 @@ class Spaces(object):
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
 
+    @staticmethod
+    def UpdateConfig(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.spaces.Spaces/UpdateConfig',
+            spaces_dot_spaces__pb2.UpdateConfigRequest.SerializeToString,
+            google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
     @staticmethod
     def Delete(request,
             target,
diff --git a/perxis/users/users_pb2.py b/perxis/users/users_pb2.py
index 0db79a24373e6604ca34e24fa6653efcb07e0c24..05cd35e27cdfedcff59d658781e96a5564daee65 100644
--- a/perxis/users/users_pb2.py
+++ b/perxis/users/users_pb2.py
@@ -22,7 +22,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=b'Z,github.com/perxteam/perxis/proto/users;users',
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\x11users/users.proto\x12\raccount.users\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1egoogle/protobuf/wrappers.proto\x1a\x13\x63ommon/common.proto\"\xcd\x01\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x12\n\nidentities\x18\x03 \x03(\t\x12\x14\n\x0c\x64isplay_name\x18\x04 \x01(\t\x12\r\n\x05\x65mail\x18\x05 \x01(\t\x12\x32\n\x0e\x65mail_verified\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x12\n\navatar_url\x18\x07 \x01(\t\x12*\n\x06system\x18\n \x01(\x0b\x32\x1a.google.protobuf.BoolValue\"\xbb\x01\n\x06\x46ilter\x12\n\n\x02id\x18\x01 \x03(\t\x12\x0c\n\x04name\x18\x02 \x03(\t\x12\x12\n\nidentities\x18\x03 \x03(\t\x12\x14\n\x0c\x64isplay_name\x18\x04 \x03(\t\x12\r\n\x05\x65mail\x18\x05 \x03(\t\x12\x32\n\x0e\x65mail_verified\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12*\n\x06system\x18\n \x01(\x0b\x32\x1a.google.protobuf.BoolValue\"4\n\rCreateRequest\x12#\n\x06\x63reate\x18\x01 \x01(\x0b\x32\x13.account.users.User\"3\n\x0e\x43reateResponse\x12!\n\x04user\x18\x01 \x01(\x0b\x32\x13.account.users.User\"\x1d\n\nGetRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t\"0\n\x0bGetResponse\x12!\n\x04user\x18\x01 \x01(\x0b\x32\x13.account.users.User\"Z\n\x0b\x46indRequest\x12%\n\x06\x66ilter\x18\x01 \x01(\x0b\x32\x15.account.users.Filter\x12$\n\x07options\x18\n \x01(\x0b\x32\x13.common.FindOptions\"A\n\x0c\x46indResponse\x12\"\n\x05users\x18\x01 \x03(\x0b\x32\x13.account.users.User\x12\r\n\x05total\x18\x02 \x01(\x03\"E\n\rUpdateRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t\x12#\n\x06update\x18\x02 \x01(\x0b\x32\x13.account.users.User\" \n\rDeleteRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t2\xd7\x02\n\x05Users\x12G\n\x06\x43reate\x12\x1c.account.users.CreateRequest\x1a\x1d.account.users.CreateResponse\"\x00\x12>\n\x03Get\x12\x19.account.users.GetRequest\x1a\x1a.account.users.GetResponse\"\x00\x12\x41\n\x04\x46ind\x12\x1a.account.users.FindRequest\x1a\x1b.account.users.FindResponse\"\x00\x12@\n\x06Update\x12\x1c.account.users.UpdateRequest\x1a\x16.google.protobuf.Empty\"\x00\x12@\n\x06\x44\x65lete\x12\x1c.account.users.DeleteRequest\x1a\x16.google.protobuf.Empty\"\x00\x42.Z,github.com/perxteam/perxis/proto/users;usersb\x06proto3'
+  serialized_pb=b'\n\x11users/users.proto\x12\raccount.users\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1egoogle/protobuf/wrappers.proto\x1a\x13\x63ommon/common.proto\"\xcd\x01\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x12\n\nidentities\x18\x03 \x03(\t\x12\x14\n\x0c\x64isplay_name\x18\x04 \x01(\t\x12\r\n\x05\x65mail\x18\x05 \x01(\t\x12\x32\n\x0e\x65mail_verified\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x12\n\navatar_url\x18\x07 \x01(\t\x12*\n\x06system\x18\n \x01(\x0b\x32\x1a.google.protobuf.BoolValue\"\xbb\x01\n\x06\x46ilter\x12\n\n\x02id\x18\x01 \x03(\t\x12\x0c\n\x04name\x18\x02 \x03(\t\x12\x12\n\nidentities\x18\x03 \x03(\t\x12\x14\n\x0c\x64isplay_name\x18\x04 \x03(\t\x12\r\n\x05\x65mail\x18\x05 \x03(\t\x12\x32\n\x0e\x65mail_verified\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12*\n\x06system\x18\n \x01(\x0b\x32\x1a.google.protobuf.BoolValue\"4\n\rCreateRequest\x12#\n\x06\x63reate\x18\x01 \x01(\x0b\x32\x13.account.users.User\"3\n\x0e\x43reateResponse\x12!\n\x04user\x18\x01 \x01(\x0b\x32\x13.account.users.User\"\x1d\n\nGetRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t\"0\n\x0bGetResponse\x12!\n\x04user\x18\x01 \x01(\x0b\x32\x13.account.users.User\"Z\n\x0b\x46indRequest\x12%\n\x06\x66ilter\x18\x01 \x01(\x0b\x32\x15.account.users.Filter\x12$\n\x07options\x18\n \x01(\x0b\x32\x13.common.FindOptions\"A\n\x0c\x46indResponse\x12\"\n\x05users\x18\x01 \x03(\x0b\x32\x13.account.users.User\x12\r\n\x05total\x18\x02 \x01(\x03\"E\n\rUpdateRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t\x12#\n\x06update\x18\x02 \x01(\x0b\x32\x13.account.users.User\" \n\rDeleteRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t\"(\n\x14GetByIdentityRequest\x12\x10\n\x08identity\x18\x01 \x01(\t\":\n\x15GetByIdentityResponse\x12!\n\x04user\x18\x01 \x01(\x0b\x32\x13.account.users.User2\xb5\x03\n\x05Users\x12G\n\x06\x43reate\x12\x1c.account.users.CreateRequest\x1a\x1d.account.users.CreateResponse\"\x00\x12>\n\x03Get\x12\x19.account.users.GetRequest\x1a\x1a.account.users.GetResponse\"\x00\x12\x41\n\x04\x46ind\x12\x1a.account.users.FindRequest\x1a\x1b.account.users.FindResponse\"\x00\x12@\n\x06Update\x12\x1c.account.users.UpdateRequest\x1a\x16.google.protobuf.Empty\"\x00\x12@\n\x06\x44\x65lete\x12\x1c.account.users.DeleteRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\\\n\rGetByIdentity\x12#.account.users.GetByIdentityRequest\x1a$.account.users.GetByIdentityResponse\"\x00\x42.Z,github.com/perxteam/perxis/proto/users;usersb\x06proto3'
   ,
   dependencies=[google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,google_dot_protobuf_dot_wrappers__pb2.DESCRIPTOR,common_dot_common__pb2.DESCRIPTOR,])
 
@@ -460,6 +460,70 @@ _DELETEREQUEST = _descriptor.Descriptor(
   serialized_end=966,
 )
 
+
+_GETBYIDENTITYREQUEST = _descriptor.Descriptor(
+  name='GetByIdentityRequest',
+  full_name='account.users.GetByIdentityRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='identity', full_name='account.users.GetByIdentityRequest.identity', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=968,
+  serialized_end=1008,
+)
+
+
+_GETBYIDENTITYRESPONSE = _descriptor.Descriptor(
+  name='GetByIdentityResponse',
+  full_name='account.users.GetByIdentityResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='user', full_name='account.users.GetByIdentityResponse.user', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1010,
+  serialized_end=1068,
+)
+
 _USER.fields_by_name['email_verified'].message_type = google_dot_protobuf_dot_wrappers__pb2._BOOLVALUE
 _USER.fields_by_name['system'].message_type = google_dot_protobuf_dot_wrappers__pb2._BOOLVALUE
 _FILTER.fields_by_name['email_verified'].message_type = google_dot_protobuf_dot_wrappers__pb2._BOOLVALUE
@@ -471,6 +535,7 @@ _FINDREQUEST.fields_by_name['filter'].message_type = _FILTER
 _FINDREQUEST.fields_by_name['options'].message_type = common_dot_common__pb2._FINDOPTIONS
 _FINDRESPONSE.fields_by_name['users'].message_type = _USER
 _UPDATEREQUEST.fields_by_name['update'].message_type = _USER
+_GETBYIDENTITYRESPONSE.fields_by_name['user'].message_type = _USER
 DESCRIPTOR.message_types_by_name['User'] = _USER
 DESCRIPTOR.message_types_by_name['Filter'] = _FILTER
 DESCRIPTOR.message_types_by_name['CreateRequest'] = _CREATEREQUEST
@@ -481,6 +546,8 @@ DESCRIPTOR.message_types_by_name['FindRequest'] = _FINDREQUEST
 DESCRIPTOR.message_types_by_name['FindResponse'] = _FINDRESPONSE
 DESCRIPTOR.message_types_by_name['UpdateRequest'] = _UPDATEREQUEST
 DESCRIPTOR.message_types_by_name['DeleteRequest'] = _DELETEREQUEST
+DESCRIPTOR.message_types_by_name['GetByIdentityRequest'] = _GETBYIDENTITYREQUEST
+DESCRIPTOR.message_types_by_name['GetByIdentityResponse'] = _GETBYIDENTITYRESPONSE
 _sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
 User = _reflection.GeneratedProtocolMessageType('User', (_message.Message,), {
@@ -553,6 +620,20 @@ DeleteRequest = _reflection.GeneratedProtocolMessageType('DeleteRequest', (_mess
   })
 _sym_db.RegisterMessage(DeleteRequest)
 
+GetByIdentityRequest = _reflection.GeneratedProtocolMessageType('GetByIdentityRequest', (_message.Message,), {
+  'DESCRIPTOR' : _GETBYIDENTITYREQUEST,
+  '__module__' : 'users.users_pb2'
+  # @@protoc_insertion_point(class_scope:account.users.GetByIdentityRequest)
+  })
+_sym_db.RegisterMessage(GetByIdentityRequest)
+
+GetByIdentityResponse = _reflection.GeneratedProtocolMessageType('GetByIdentityResponse', (_message.Message,), {
+  'DESCRIPTOR' : _GETBYIDENTITYRESPONSE,
+  '__module__' : 'users.users_pb2'
+  # @@protoc_insertion_point(class_scope:account.users.GetByIdentityResponse)
+  })
+_sym_db.RegisterMessage(GetByIdentityResponse)
+
 
 DESCRIPTOR._options = None
 
@@ -563,8 +644,8 @@ _USERS = _descriptor.ServiceDescriptor(
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=969,
-  serialized_end=1312,
+  serialized_start=1071,
+  serialized_end=1508,
   methods=[
   _descriptor.MethodDescriptor(
     name='Create',
@@ -616,6 +697,16 @@ _USERS = _descriptor.ServiceDescriptor(
     serialized_options=None,
     create_key=_descriptor._internal_create_key,
   ),
+  _descriptor.MethodDescriptor(
+    name='GetByIdentity',
+    full_name='account.users.Users.GetByIdentity',
+    index=5,
+    containing_service=None,
+    input_type=_GETBYIDENTITYREQUEST,
+    output_type=_GETBYIDENTITYRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
 ])
 _sym_db.RegisterServiceDescriptor(_USERS)
 
diff --git a/perxis/users/users_pb2_grpc.py b/perxis/users/users_pb2_grpc.py
index a2f18c5c6e658ebe3d09c603f59bb12bcc7c528f..bad655096accb000f8141615c0b588a9e40c9265 100644
--- a/perxis/users/users_pb2_grpc.py
+++ b/perxis/users/users_pb2_grpc.py
@@ -40,6 +40,11 @@ class UsersStub(object):
                 request_serializer=users_dot_users__pb2.DeleteRequest.SerializeToString,
                 response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
                 )
+        self.GetByIdentity = channel.unary_unary(
+                '/account.users.Users/GetByIdentity',
+                request_serializer=users_dot_users__pb2.GetByIdentityRequest.SerializeToString,
+                response_deserializer=users_dot_users__pb2.GetByIdentityResponse.FromString,
+                )
 
 
 class UsersServicer(object):
@@ -83,6 +88,14 @@ class UsersServicer(object):
         context.set_details('Method not implemented!')
         raise NotImplementedError('Method not implemented!')
 
+    def GetByIdentity(self, request, context):
+        """Метод для внутреннего использования. Недоступен для внешних
+        запросов - авторизация вернет ошибку `access denied`
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
 
 def add_UsersServicer_to_server(servicer, server):
     rpc_method_handlers = {
@@ -111,6 +124,11 @@ def add_UsersServicer_to_server(servicer, server):
                     request_deserializer=users_dot_users__pb2.DeleteRequest.FromString,
                     response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
             ),
+            'GetByIdentity': grpc.unary_unary_rpc_method_handler(
+                    servicer.GetByIdentity,
+                    request_deserializer=users_dot_users__pb2.GetByIdentityRequest.FromString,
+                    response_serializer=users_dot_users__pb2.GetByIdentityResponse.SerializeToString,
+            ),
     }
     generic_handler = grpc.method_handlers_generic_handler(
             'account.users.Users', rpc_method_handlers)
@@ -205,3 +223,20 @@ class Users(object):
             google_dot_protobuf_dot_empty__pb2.Empty.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def GetByIdentity(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/account.users.Users/GetByIdentity',
+            users_dot_users__pb2.GetByIdentityRequest.SerializeToString,
+            users_dot_users__pb2.GetByIdentityResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/proto/clients/clients.proto b/proto/clients/clients.proto
new file mode 100644
index 0000000000000000000000000000000000000000..07b6b511895e4f33651a298a97a25b96728c42a5
--- /dev/null
+++ b/proto/clients/clients.proto
@@ -0,0 +1,112 @@
+syntax = "proto3";
+
+import "google/protobuf/empty.proto";
+import "common/common.proto";
+
+option go_package = "github.com/perxteam/perxis/proto/clients;clients";
+
+package content.clients;
+
+message Client {
+  string id = 1;
+  string space_id = 2;
+  string name = 3;
+  string client_id = 4;
+  string auth_id = 5;
+  string description = 6;
+  optional bool disabled = 7;
+  repeated string environments = 8;
+  repeated common.Rule rules = 9;
+}
+
+message CreateRequest {
+  Client client = 1;
+}
+
+message CreateResponse {
+  Client created = 1;
+}
+
+message GetRequest {
+  string space_id = 1;
+  string id = 2;
+}
+
+message GetResponse {
+  Client client = 1;
+}
+
+message GetByClientIDRequest {
+  string space_id = 1;
+  string client_id = 2;
+  string auth_id = 3;
+}
+
+message GetByClientIDResponse {
+  Client client = 1;
+}
+
+message UpdateRequest {
+  Client client = 1;
+}
+
+message ListRequest {
+  string space_id = 1;
+}
+
+message ListResponse {
+  repeated Client clients = 1;
+}
+
+message DeleteRequest {
+  string space_id = 1;
+  string id = 2;
+}
+
+message EnableRequest {
+  string space_id = 1;
+  string id = 2;
+  bool enable = 3;
+}
+
+message SetRuleRequest {
+  string space_id = 1;
+  string id = 2;
+  common.Rule rule = 3;
+}
+
+message RemoveRuleRequest {
+  string space_id = 1;
+  string id = 2;
+  string rule_id = 3;
+}
+
+service Clients  {
+
+  // Create - создает клиента (приложение) для работы с API
+  rpc Create(CreateRequest) returns(CreateResponse) {}
+
+  // Get - возвращает клиента по id
+  rpc Get(GetRequest) returns(GetResponse) {}
+
+  // GetByClientID - возвращает клиента по clientId системы авторизации
+  rpc GetByClientID(GetByClientIDRequest) returns(GetByClientIDResponse) {}
+
+  // Update - обновляет параметры клиента
+  rpc Update(UpdateRequest) returns(google.protobuf.Empty) {}
+
+  // List - возвращает список клиентов созданных в пространстве
+  rpc List(ListRequest) returns(ListResponse) {}
+
+  // Delete - удаляет указанного клиента из пространстве
+  rpc Delete(DeleteRequest) returns(google.protobuf.Empty) {}
+
+  // Enable - активирует/деактивирует клиента. Клиент не сможет обращаться к API платформы
+  rpc Enable(EnableRequest) returns(google.protobuf.Empty) {}
+
+  // SetRule - добавляет клиенту правила доступа к API
+  rpc SetRule(SetRuleRequest) returns(google.protobuf.Empty) {}
+
+  // SetRule - удаляет правилу с указанным Id
+  rpc RemoveRule(RemoveRuleRequest) returns(google.protobuf.Empty) {}
+}
diff --git a/proto/collaborators/collaborators.proto b/proto/collaborators/collaborators.proto
index 5d539dc0e29a6168922db139718c9766b1eb88ed..7364cb41b70609727cae5e9dbef709eed816adc6 100644
--- a/proto/collaborators/collaborators.proto
+++ b/proto/collaborators/collaborators.proto
@@ -1,17 +1,12 @@
 syntax = "proto3";
 
 import "google/protobuf/empty.proto";
+import "common/common.proto";
 
 option go_package = "github.com/perxteam/perxis/proto/collaborators;collaborators";
 
 package content.collaborators;
 
-message Collaborator {
-  string space_id = 1;
-  string user_id = 2;
-  string role = 3;
-}
-
 message SetRequest {
   string space_id = 1;
   string user_id = 2;
@@ -37,7 +32,7 @@ message ListCollaboratorsRequest {
 }
 
 message ListCollaboratorsResponse {
-  repeated Collaborator collaborators = 1;
+  repeated common.Collaborator collaborators = 1;
 }
 
 message ListSpacesRequest {
@@ -45,7 +40,7 @@ message ListSpacesRequest {
 }
 
 message ListSpacesResponse {
-  repeated Collaborator spaces = 1;
+  repeated common.Collaborator spaces = 1;
 }
 
 service Collaborators {
diff --git a/proto/collections/collections.proto b/proto/collections/collections.proto
index eaa48cf3cc5118ef8f53494317e22841228ac8c9..033fd17e374fb4bcb1258b4e1176811902d85dc1 100644
--- a/proto/collections/collections.proto
+++ b/proto/collections/collections.proto
@@ -1,7 +1,7 @@
 syntax = "proto3";
 
 import "google/protobuf/empty.proto";
-import "google/protobuf/wrappers.proto";
+//import "google/protobuf/wrappers.proto";
 
 option go_package = "github.com/perxteam/perxis/proto/collections;collections";
 
@@ -12,22 +12,16 @@ message Collection {
   string space_id = 2;
   string env_id = 3;
   string name = 4;
-  bool single = 5;
-  bool system = 6;
+  optional bool single = 5;
+  optional bool system = 6;
   string schema = 7;
 }
 
 message CreateRequest {
-  string space_id = 1;
-  string env_id = 2;
-  string collection_id = 3;
-  string name = 4;
-  bool single = 5;
-  bool system = 6;
-  string schema = 7;
+  Collection coll = 1;
 }
 message CreateResponse {
-  Collection collection = 1;
+  Collection created = 1;
 }
 
 message GetRequest {
@@ -49,12 +43,7 @@ message ListResponse {
 }
 
 message UpdateRequest {
-  string space_id = 1;
-  string env_id = 2;
-  string collection_id = 3;
-  string name = 4;
-  google.protobuf.BoolValue single = 5;
-  string schema = 6;
+  Collection coll = 1;
 }
 
 message DeleteRequest {
diff --git a/proto/common/common.proto b/proto/common/common.proto
index 9008b19e553c2d8515daf732cb796ea2d4dc88cb..34ea24e654c3adbf7943ef046279194d2cfd334b 100644
--- a/proto/common/common.proto
+++ b/proto/common/common.proto
@@ -153,9 +153,9 @@ message ContentRule {
 
 enum ItemAccess {
   NONE = 0;
-  ANY = 1;
-  MINE = 2;
-  ROLE = 3;
+//  ANY = 1;
+//  MINE = 2;
+//  ROLE = 3;
 }
 
 message Filter {
@@ -176,4 +176,34 @@ message FindOptions {
   repeated string sort = 1;
   int32 page_num = 2;
   int32 page_size = 3;
-}
\ No newline at end of file
+}
+
+
+enum Access {
+  ANY = 0;
+  MINE = 1;
+  ROLE = 2;
+}
+
+enum Action {
+  UNKNOWN = 0;
+  CREATE = 1;
+  READ = 2;
+  UPDATE = 3;
+  DELETE = 4;
+}
+
+message Rule {
+  string id = 1;
+  string collection_id = 2;
+  repeated Action actions = 3;
+  Access access = 4;
+  repeated string fields = 6;
+  bool fields_allowed = 7;
+}
+
+message Collaborator {
+  string space_id = 1;
+  string user_id = 2;
+  string role = 3;
+}
diff --git a/proto/environments/environments.proto b/proto/environments/environments.proto
index 45bd93ecde60b7b08a915c5e9790d65ce3a54bfb..18b4593d182af866df9f56ad8dbdf135335c79e5 100644
--- a/proto/environments/environments.proto
+++ b/proto/environments/environments.proto
@@ -8,26 +8,32 @@ package content.environments;
 
 message Environment {
   string id = 1;
-  string description = 2;
+  string space_id = 2;
+  string description = 3;
   enum State {
     UNKNOWN = 0;
-    PREPARING = 1;
-    READY = 2;
-    FAILED = 3;
+    NEW = 1;
+    PREPARING = 2;
+    READY = 3;
+    ERROR = 4;
   }
-  State state = 3;
-  repeated string aliases = 5;
+  State state = 4;
+  string state_info = 5;
+  repeated string aliases = 6;
+  Config config = 10;
+}
+
+message Config {
+  string source_id = 1;
+  repeated string features = 2;
 }
 
 message CreateRequest {
-  string space_id = 1;
-  string base_id = 2;
-  string env_id = 3;
-  string description  = 4;
+  Environment env = 1;
 }
 
 message CreateResponse {
-  Environment env = 1;
+  Environment created = 1;
 }
 
 message ListRequest {
@@ -48,9 +54,7 @@ message GetResponse {
 }
 
 message UpdateRequest {
-  string space_id = 1;
-  string env_id = 2;
-  string description  = 3;
+  Environment env = 1;
 }
 
 message SetAliasRequest {
diff --git a/proto/invitations/invitations.proto b/proto/invitations/invitations.proto
index 3cf89d11a7a5e84688c8ed7565c08dc4e63d07a1..14e6131bb55942b066092e053bf2baa1f3ba1337 100644
--- a/proto/invitations/invitations.proto
+++ b/proto/invitations/invitations.proto
@@ -11,7 +11,7 @@ package content.invitations;
 message Invitation {
   string id = 1;
   string email = 2;
-  string organization_id = 3;
+  string org_id = 3;
   string space_id = 4;
   string owner_id = 5;
   string role = 6;
@@ -22,7 +22,7 @@ message Invitation {
 message Filter {
   repeated string id = 1;
   repeated string email = 2;
-  repeated string organization_id = 3;
+  repeated string org_id = 3;
   repeated string space_id = 4;
   repeated string owner_id = 5;
   repeated string role = 6;
@@ -35,11 +35,7 @@ message FindOptions {
 }
 
 message CreateRequest {
-  string email = 1;
-  string space_id = 2;
-  string role = 3;
-  string owner_id = 4;
-  google.protobuf.Timestamp valid_until = 5;
+  Invitation invitation = 1;
 }
 
 message CreateResponse {
diff --git a/proto/items/items.proto b/proto/items/items.proto
new file mode 100644
index 0000000000000000000000000000000000000000..6aada62f44a721f2627e616742d0f80d47f04c08
--- /dev/null
+++ b/proto/items/items.proto
@@ -0,0 +1,176 @@
+syntax = "proto3";
+
+import "google/protobuf/empty.proto";
+import "common/common.proto";
+import "google/protobuf/timestamp.proto";
+import "google/protobuf/struct.proto";
+
+option go_package = "github.com/perxteam/perxis/proto/items;items";
+
+package content.items;
+
+message Item {
+  enum State {
+    DRAFT = 0;
+    PUBLISHED = 1;
+  }
+  string id = 1;
+  string space_id = 2;
+  string env_id = 3;
+  string collection_id = 4;
+  State state = 5;
+  google.protobuf.Timestamp created_at = 6;
+  string created_by = 7;
+  google.protobuf.Struct data = 8;
+  map<string, google.protobuf.Struct> translations = 9;
+  string revision_id = 10;
+  google.protobuf.Timestamp published_at = 11;
+  string published_by = 12;
+  google.protobuf.Timestamp archived_at = 13;
+  string archived_by = 14;
+}
+
+message Filter {
+  repeated string id = 1;
+  repeated common.Filter data = 2;
+}
+
+message CreateRequest {
+  Item item = 1;
+}
+message CreateResponse {
+  Item created = 1;
+}
+
+message GetRequest {
+  string space_id = 1;
+  string env_id = 2;
+  string collection_id = 3;
+  string item_id = 4;
+}
+message GetResponse {
+  Item item = 1;
+}
+
+message FindRequest {
+  string space_id = 1;
+  string env_id = 2;
+  string collection_id = 3;
+  Filter filter = 4;
+  common.FindOptions options = 5;
+}
+message FindResponse{
+  repeated Item items = 1;
+  int32 total = 2;
+}
+
+message UpdateRequest {
+  Item item = 1;
+}
+
+message DeleteRequest {
+  string space_id = 1;
+  string env_id = 2;
+  string collection_id = 3;
+  string item_id = 4;
+}
+
+message PublishRequest {
+  Item item = 1;
+}
+
+message UnpublishRequest {
+  string space_id = 1;
+  string env_id = 2;
+  string collection_id = 3;
+  string item_id = 4;
+}
+
+message GetPublishedRequest {
+  string space_id = 1;
+  string env_id = 2;
+  string collection_id = 3;
+  string locale_id = 4;
+  string item_id = 5;
+}
+message GetPublishedResponse {
+  Item item = 1;
+}
+
+message FindPublishedRequest {
+  string space_id = 1;
+  string env_id = 2;
+  string collection_id = 3;
+  string locale_id = 4;
+  Filter filter = 5;
+  common.FindOptions options = 6;
+}
+message FindPublishedResponse{
+  repeated Item items = 1;
+  int32 total = 2;
+}
+
+message GetRevisionRequest {
+  string space_id = 1;
+  string env_id = 2;
+  string collection_id = 3;
+  string item_id = 4;
+  string revision_id = 5;
+}
+message GetRevisionResponse {
+  Item item = 1;
+}
+
+message ListRevisionsRequest {
+  string space_id = 1;
+  string env_id = 2;
+  string collection_id = 3;
+  string item_id = 4;
+}
+message ListRevisionsResponse {
+  repeated Item items = 1;
+}
+
+message ArchiveRequest {
+  Item item = 1;
+}
+
+message UnarchiveRequest {
+  string space_id = 1;
+  string env_id = 2;
+  string collection_id = 3;
+  string item_id = 4;
+}
+
+message FindArchivedRequest {
+  string space_id = 1;
+  string env_id = 2;
+  string collection_id = 3;
+  Filter filter = 5;
+  common.FindOptions options = 6;
+}
+message FindArchivedResponse{
+  repeated Item items = 1;
+  int32 total = 2;
+}
+
+service Items {
+
+  rpc Create(CreateRequest) returns(CreateResponse) {}
+  rpc Get(GetRequest) returns(GetResponse) {}
+  rpc Find(FindRequest) returns(FindResponse) {}
+  rpc Update(UpdateRequest) returns(google.protobuf.Empty) {}
+  rpc Delete(DeleteRequest) returns(google.protobuf.Empty) {}
+
+  rpc Publish(PublishRequest) returns(google.protobuf.Empty) {}
+  rpc Unpublish(UnpublishRequest) returns(google.protobuf.Empty) {}
+  rpc GetPublished(GetPublishedRequest) returns(GetPublishedResponse) {}
+  rpc FindPublished(FindPublishedRequest) returns(FindPublishedResponse) {}
+
+  rpc GetRevision(GetRevisionRequest) returns(GetRevisionResponse) {}
+  rpc ListRevisions(ListRevisionsRequest) returns(ListRevisionsResponse) {}
+
+  rpc Archive(ArchiveRequest) returns(google.protobuf.Empty) {}
+  rpc FindArchived(FindArchivedRequest) returns(FindArchivedResponse) {}
+  rpc Unarchive(UnarchiveRequest) returns(google.protobuf.Empty) {}
+}
diff --git a/proto/locales/locales.proto b/proto/locales/locales.proto
index e9ad6c95e4a888ac9699c06c837d2d472d320913..a381d684cf3c4cc321b946078c4903f01be00c48 100644
--- a/proto/locales/locales.proto
+++ b/proto/locales/locales.proto
@@ -8,14 +8,12 @@ package content.locales;
 
 message Locale {
   string id = 1;
-  string name = 2;
-  string space_id = 3;
+  string space_id = 2;
+  string name = 3;
 }
 
 message CreateRequest {
-  string locale_id = 1;
-  string name = 2;
-  string space_id  = 3;
+  Locale locale = 1;
 }
 
 message CreateResponse {
@@ -30,8 +28,8 @@ message ListResponse {
 }
 
 message DeleteRequest {
-  string locale_id = 1;
-  string space_id = 2;
+  string space_id = 1;
+  string locale_id = 2;
 }
 
 service Locales {
diff --git a/proto/members/members.proto b/proto/members/members.proto
index 149f98e00ba64654120d1b29a71e621813b7abfe..5158499d1a72ef1ee0a7cf049ffbb5c306dbc3cb 100644
--- a/proto/members/members.proto
+++ b/proto/members/members.proto
@@ -1,6 +1,7 @@
 syntax = "proto3";
 
 import "google/protobuf/empty.proto";
+import "common/common.proto";
 
 option go_package = "github.com/perxteam/perxis/proto/members;members";
 
@@ -63,3 +64,13 @@ service Members {
   rpc ListMembers(ListMembersRequest) returns(ListMembersResponse) {}
   rpc ListOrganizations(ListOrganizationsRequest) returns(ListOrganizationsResponse) {}
 }
+
+// Внутренний сервис (часть имплементации паттерна Observer). Используется для установки
+// членства в организации при принятии приглашения в пространство
+message OnCollaboratorSetRequest {
+  common.Collaborator collaborator = 1;
+}
+
+service Observer {
+  rpc OnCollaboratorSet(OnCollaboratorSetRequest) returns(google.protobuf.Empty) {}
+}
diff --git a/proto/organizations/organizations.proto b/proto/organizations/organizations.proto
index a08f7e6f4f461db8fee205b277fde38eed1836bb..7a8d4c0ffe7c1aefb0e32229cf917df5800b598d 100644
--- a/proto/organizations/organizations.proto
+++ b/proto/organizations/organizations.proto
@@ -13,19 +13,17 @@ message Organization {
   string name = 2; // Имя организации
   string description = 3; // Описание организации
   string logo_url = 5; // URI изображения логотипа
+  optional string owner_id = 6;
 }
 
 // Запросы и ответы
 
 message CreateRequest {
-  string name = 1;
-  string description = 2;
-  string logo_url = 3;
-  string owner_id = 4;
+  Organization org = 1;
 }
 
 message CreateResponse {
-  Organization org = 1;
+  Organization created = 1;
 }
 
 message GetRequest {
@@ -36,15 +34,10 @@ message GetResponse {
   Organization org = 1;
 }
 
-
 message UpdateRequest {
-  string org_id = 1;
-  string name = 2;
-  string description = 3;
-  string logo_url = 4;
+  Organization org = 1;
 }
 
-
 message DeleteRequest {
   string org_id = 1;
 }
diff --git a/proto/roles/roles.proto b/proto/roles/roles.proto
new file mode 100644
index 0000000000000000000000000000000000000000..78f4453795174b26b2be77f8c0d1aa092cc60de1
--- /dev/null
+++ b/proto/roles/roles.proto
@@ -0,0 +1,86 @@
+syntax = "proto3";
+
+import "google/protobuf/empty.proto";
+import "common/common.proto";
+
+option go_package = "github.com/perxteam/perxis/proto/roles;roles";
+
+package content.roles;
+
+message Role {
+  string id = 1;
+  string space_id = 2;
+  string name = 3;
+  string description = 4;
+  repeated common.Rule rules = 5;
+}
+
+message CreateRequest {
+  Role role = 1;
+}
+
+message CreateResponse {
+  Role created = 1;
+}
+
+message GetRequest {
+  string space_id = 1;
+  string role_id = 2;
+}
+
+message GetResponse {
+  Role role = 1;
+}
+
+message UpdateRequest {
+  Role role = 1;
+}
+
+message ListRequest {
+  string space_id = 1;
+}
+
+message ListResponse {
+  repeated Role roles = 1;
+}
+
+message DeleteRequest {
+  string space_id = 1;
+  string role_id = 2;
+}
+
+message SetRuleRequest {
+  string space_id = 1;
+  string role_id = 2;
+  common.Rule rule = 3;
+}
+
+message RemoveRuleRequest {
+  string space_id = 1;
+  string role_id = 2;
+  string rule_id = 3;
+}
+
+service Roles  {
+
+  // Create - создает роль в рамках пространства
+  rpc Create(CreateRequest) returns(CreateResponse) {}
+
+  // Get - возвращает роль по id
+  rpc Get(GetRequest) returns(GetResponse) {}
+
+  // Update - обновляет параметры роли
+  rpc Update(UpdateRequest) returns(google.protobuf.Empty) {}
+
+  // List - возвращает список ролей, созданных в пространстве
+  rpc List(ListRequest) returns(ListResponse) {}
+
+  // Delete - удаляет указанную роль из пространстве
+  rpc Delete(DeleteRequest) returns(google.protobuf.Empty) {}
+
+  // SetRule - добавляет правило доступа к API для роли
+  rpc SetRule(SetRuleRequest) returns(google.protobuf.Empty) {}
+
+  // RemoveRule - удаляет правило для роли
+  rpc RemoveRule(RemoveRuleRequest) returns(google.protobuf.Empty) {}
+}
\ No newline at end of file
diff --git a/proto/spaces/spaces.proto b/proto/spaces/spaces.proto
index 8aeccd6e38615da8d91f385a0336f8f0f56aa0bb..99bfe6f467b5c91d68768a5dec6b0ce633bcdb71 100644
--- a/proto/spaces/spaces.proto
+++ b/proto/spaces/spaces.proto
@@ -8,7 +8,7 @@ import "google/protobuf/empty.proto";
 
 message Space {
   string id = 1;
-  string organization_id = 2;
+  string org_id = 2;
   string name = 3;
   string description = 4;
   State state = 5;
@@ -23,6 +23,7 @@ enum State {
   MAINTENANCE = 4;
   MIGRATION = 5;
   DELETING = 6;
+  ERROR = 7;
 }
 
 message Config {
@@ -30,14 +31,11 @@ message Config {
 }
 
 message CreateRequest {
-  string org_id = 1;
-  string name = 2;
-  string description = 3;
-  Config config = 5;
+  Space space = 1;
 }
 
 message CreateResponse {
-  Space space = 1;
+  Space created = 1;
 }
 
 message GetRequest {
@@ -56,14 +54,14 @@ message ListResponse {
   repeated Space spaces = 1;
 }
 
-
 message UpdateRequest {
-  string space_id = 1;
-  string name = 2;
-  string description = 3;
-  Config config = 5;
+  Space space = 1;
 }
 
+message UpdateConfigRequest {
+  string space_id = 1;
+  Config config = 2;
+}
 
 message DeleteRequest {
   string space_id = 1;
@@ -74,5 +72,6 @@ service Spaces {
   rpc Get(GetRequest) returns(GetResponse) {}
   rpc List(ListRequest) returns(ListResponse) {}
   rpc Update(UpdateRequest) returns(google.protobuf.Empty) {}
+  rpc UpdateConfig(UpdateConfigRequest) returns(google.protobuf.Empty) {}
   rpc Delete(DeleteRequest) returns(google.protobuf.Empty) {}
 }
diff --git a/proto/users/users.proto b/proto/users/users.proto
index 46d164c334c97203c342a577c4c0a3a3d4675a89..664645b416b504c7f9d66fe699a0b956f9654592 100644
--- a/proto/users/users.proto
+++ b/proto/users/users.proto
@@ -66,6 +66,14 @@ message DeleteRequest {
   string user_id = 1;
 }
 
+message GetByIdentityRequest {
+  string identity = 1;
+}
+
+message GetByIdentityResponse {
+  User user = 1;
+}
+
 service Users  {
   // Создание пользователя или регистрация текущего пользователя в системе, если create.id == `current`
   rpc Create(CreateRequest) returns(CreateResponse) {}
@@ -84,4 +92,8 @@ service Users  {
   //  - Удаление существующего пользователя по идентификатору
   //  - Удаление текущего пользователя по спец. идентификатору `current`
   rpc Delete(DeleteRequest) returns(google.protobuf.Empty) {}
+
+  // Метод для внутреннего использования. Недоступен для внешних
+  // запросов - авторизация вернет ошибку `access denied`
+  rpc GetByIdentity(GetByIdentityRequest) returns(GetByIdentityResponse) {}
 }
diff --git a/requirements.txt b/requirements.txt
index 065ecba9b36ce909ed5d56f8042b1339503c3fcb..aff5ac72cc398cc837230414377e68b41f048ef9 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,6 +1,6 @@
 certifi==2020.12.5
 chardet==4.0.0
-grpcio==1.36.1
+grpcio==1.37.0
 idna==2.10
 oauthlib==3.1.0
 protobuf==3.15.4