Working with the user object

Working with the user object

The user object gives you information about the user themselves, the state of the user account, as well as the permissions and access levels assigned to that account.

In this guide, we'll explore the user object and show how to check if they have the permissions to access a given entity.

Get started

This guide uses the example API client at https://github.com/zed-eiq/eiq_simpleclient_demo.

To get started:

  1. Install the eiq_simpleclient_demo library with pip.
  2. Initialize the APIClient object with your Intelligence Center URL and API key.
# Install the demo REST API client from https://github.com/zed-eiq/eiq_simpleclient_demo
python -m pip install git+https://github.com/zed-eiq/eiq_simpleclient_demo.git --quiet
  Building wheel for eiq-simpleclient-demo (setup.py) ... 
from eiq_simpleclient import APIClient
from pprint import pprint as pp
from getpass import getpass

# Ask for API key
API_KEY = getpass('Enter your API key:')

BASEURL = "https://ic-playground.eclecticiq.com/api/beta"

client = APIClient(BASEURL, API_KEY)
Enter your API key:··········

Required permissions

To run the examples in this guide, your user account should have at least these permissions:

  • read permissions
  • read groups
  • read roles
  • read sources
  • read entities

See User permissions for more information.

Get the current user

Retrieve the User object for the current user.

current_user = client.get("users/self")["data"] # remove the `data` wrapper
pp(f"My user account: {current_user['username']}")
'My user account: api-docs'

What permissions does this user have?

To figure out what permissions a user has, we need to look at the user's:

  • Groups
  • Roles

A user inherits from its groups:

  • Allowed roles
  • Allowed sources and their allowed TLP

The Traffic Light Protocol (TLP) color associated with a source determines the level of restricted content that the Group's users are allowed to access.

Users in the group can only access entities and observables that have a TLP value that is equally or less restrictive than the allowed TLP value.

For example, if an allowed source is assigned the TLP color GREEN, then users in that group can only access entities and observables that have been set to TLP GREEN or WHITE.

A user inherits from its roles:

  • Permissions

The User object retrieved from the /users endpoint shows the end-result of these assignments in their permissions and sources fields. However, these properties are not managed on the User object itself, but on the groups and roles that the user inherits these properties from.

The following code example shows how to get the sources both from a group object and the current user object:

# Current user's groups
user_groups = current_user["groups"]

print("This user's groups:")
pp([client.resolve(group) for group in user_groups])

# Allowed sources that user inherits from this group
print("\nUser inherits all allowed sources from its groups:")
pp(current_user["sources"])
This user's groups:
[{'data': {'created_at': '2022-03-03T09:32:16.898431+00:00',
           'description': None,
           'id': 21,
           'last_updated_at': '2022-03-03T09:32:16.898431+00:00',
           'name': 'APIDocs',
           'sources': ['https://ic-playground.eclecticiq.com/api/beta/sources/ce87c556-0abd-46ca-80ca-03bb748bb751?allowed_tlp=RED',
                       'https://ic-playground.eclecticiq.com/api/beta/sources/77261a46-2ac1-475f-99de-0da5a40c29ef?allowed_tlp=RED',
                       'https://ic-playground.eclecticiq.com/api/beta/sources/f533dc6b-98e7-4bdd-8326-570093f0e191?allowed_tlp=RED',
                       'https://ic-playground.eclecticiq.com/api/beta/sources/25231f86-d3eb-4418-9122-e43310fde3bd?allowed_tlp=RED']}}]

User inherits all allowed sources from its groups:
['https://ic-playground.eclecticiq.com/api/beta/sources/77261a46-2ac1-475f-99de-0da5a40c29ef?allowed_tlp=RED',
 'https://ic-playground.eclecticiq.com/api/beta/sources/f533dc6b-98e7-4bdd-8326-570093f0e191?allowed_tlp=RED',
 'https://ic-playground.eclecticiq.com/api/beta/sources/25231f86-d3eb-4418-9122-e43310fde3bd?allowed_tlp=RED',
 'https://ic-playground.eclecticiq.com/api/beta/sources/ce87c556-0abd-46ca-80ca-03bb748bb751?allowed_tlp=RED']
# Current user's roles
user_roles = current_user["roles"]

print("""Retrieving the user's roles gives us the following role objects:""")
pp([client.resolve(role) for role in user_roles])

# Permissions user inherits from its roles
print("""
User inherits all permissions from its assigned roles.
We can see that the user object's "permissions" field contains
the same permissions as the permissions contained in its assigned roles:""")
pp(current_user["permissions"])
Retrieving the user's roles gives us the following role objects:
[{'data': {'created_at': '2022-03-03T09:45:14.979712+00:00',
           'description': 'For documenting APIs through public Jupyter '
                          'Notebooks',
           'id': 8,
           'last_updated_at': '2022-03-28T09:04:05.448142+00:00',
           'name': 'API Docs role',
           'permissions': ['https://ic-playground.eclecticiq.com/api/beta/permissions/17',
                           'https://ic-playground.eclecticiq.com/api/beta/permissions/45',
                           'https://ic-playground.eclecticiq.com/api/beta/permissions/51',
                           'https://ic-playground.eclecticiq.com/api/beta/permissions/73']}}]

User inherits all permissions from its assigned roles.
We can see that the user object's "permissions" field contains
the same permissions as the permissions contained in its assigned roles:
['https://ic-playground.eclecticiq.com/api/beta/permissions/17',
 'https://ic-playground.eclecticiq.com/api/beta/permissions/45',
 'https://ic-playground.eclecticiq.com/api/beta/permissions/51',
 'https://ic-playground.eclecticiq.com/api/beta/permissions/73']

Sources

All entities and observables belong to a source.

To access a given entity or observable, users must be at least a member in a group where the source of that entity or observable is one of the Allowed sources for that group.

The following code example shows getting an entity, and then comparing it's sources field to our current user's sources field:

📔

Each member of the sources list in a group or user object may contain an allowed_tlp query parameter that contains the maximum allowed TLP (inclusive) that the group or user is assigned.

The allowed_tlp parameter may not be present in the sources of entities and other objects. This means that you may need to strip the allowed_tlp query when comparing a group or user object's sources field with the sources field of another object.

print("""Get a single entity, and display its title, id, and sources fields:
""")
one_entity = client.get("entities", {"limit": 1})["data"][0]
pp({
    "title": one_entity["data"]["title"],
    "id": one_entity["data"]["id"],
    "sources": one_entity["sources"]
    })

print("\nThe retrieved entity must have a source that is in the user object's 'sources' field:")
for source in current_user["sources"]:
  for entity_source in one_entity["sources"]:
    if entity_source in source:
      # We do a substring comparison here to account for the ``allowed_tlp``
      # query parameter in the user object's ``sources`` field
      print(">>> This source is one of the user's allowed sources:", entity_source)
Get a single entity, and display its title, id, and sources fields:

{'id': '{https://www.eclecticiq.com/ns}indicator-a8b9f982-39c0-44d4-97fe-b54c10813a01',
 'sources': ['https://ic-playground.eclecticiq.com/api/beta/sources/f533dc6b-98e7-4bdd-8326-570093f0e191'],
 'title': 'http://117.201.34.54:35392/Mozi.m'}

The retrieved entity must have a source that is in the user object's 'sources' field:
>>> This source is one of the user's allowed sources: https://ic-playground.eclecticiq.com/api/beta/sources/f533dc6b-98e7-4bdd-8326-570093f0e191

Cannot retrieve entity from a source that is not in user's allowed sources list

Attempting to retrieve entities that belong to a source that is not in the user object's sources list will fail:

unknown_source = "https://ic-playground.eclecticiq.com/api/beta/sources/73c65806-a5c1-43df-bbc4-f2234319097d"

for source in current_user["sources"]:
  if unknown_source in source:
    print(">>> This source is one of the user's allowed sources:", unknown_source)
  else:
    print(f">>> {unknown_source} is not one of the user's allowed sources")


print("""
Attempting to retrieve an entity whose ``sources`` value is not one
of the user object's allowed sources will fail:""")
cannot_get_entities = client.get("entities", {"filter[sources]": unknown_source})
pp(cannot_get_entities)
>>> https://ic-playground.eclecticiq.com/api/beta/sources/73c65806-a5c1-43df-bbc4-f2234319097d is not one of the user's allowed sources
>>> https://ic-playground.eclecticiq.com/api/beta/sources/73c65806-a5c1-43df-bbc4-f2234319097d is not one of the user's allowed sources
>>> https://ic-playground.eclecticiq.com/api/beta/sources/73c65806-a5c1-43df-bbc4-f2234319097d is not one of the user's allowed sources
>>> https://ic-playground.eclecticiq.com/api/beta/sources/73c65806-a5c1-43df-bbc4-f2234319097d is not one of the user's allowed sources

Attempting to retrieve an entity whose ``sources`` value is not one
of the user object's allowed sources will fail:
{'errors': [{'detail': 'Source value not allowed',
             'status': 400,
             'title': 'Validation failed'}]}