Synapse Admin Guide

This guide is designed for use by Synapse Administrators (“global admins”). Synapse Admins are typically Synapse power-users with admin=true privileges on the Cortex who are responsible for configuration and management of a production instance of Synapse.

The Synapse Admin Guide provides important instructions and background information on topics related to day-to-day Synapse administrative tasks, and focuses on using Storm to carry out those tasks.

Synapse provides a number of additional methods that can be used to perform some or all of the tasks described in this guide; however, these methods are not covered here. Additional methods include:

Tip

If you are a commercial Synapse user with the Synapse UI (Optic), see the UI documentation for information on performing Synapse Admin tasks using Optic. Optic simplifies many of Synapse’s administrative tasks. However, we encourage you to review the information in this guide for important background and an overview of the relevant topics.

Enable Synapse Power-Ups

The Vertex Project provides a number of Power-Ups that extend the functionality of Synapse. For more information on configuring your Cortex to use Rapid Power-Ups, see the blog post on Synapse Power-Ups.

Note

Advanced Power-Ups are deployed via their own Docker containers and are typically configured by a DevOps team.

Create and Manage Users and Roles

A User account is required to authenticate to and access Synapse. Having “a Synapse account” effectively means having an account in the Cortex.

In Synapse, a Role can be used to “group” users with similar responsibilities (and related permissions requirements). You can grant or revoke one or more roles from a user.

You grant (or deny) permissions to users or roles by assigning rules that specify those permissions (see Assign and Manage Permissions).

Synapse includes the following built-in users and roles:

  • Root user. The root account has Admin privileges in the Cortex. The admin status of the root account cannot be revoked, and the account cannot be locked / disabled.

  • All role. The all role has read access to the Cortex (specifically, to any view with worldreadable=true, which includes the default view). All user accounts are automatically granted the all role (are part of the all “group”); this role cannot be revoked.

Tip

The set of Storm auth commands are collectively used to manage users, roles, and permissions from Storm.

In the commercial Optic UI, users, roles, and permissions can be managed through the Admin Tool and through dialogs associated with various objects (such as Views or Stories).

Note

The descriptions and examples below assume that you have deployed Synapse using native Synapse management and authentication of users, roles, and permissions.

The Synapse Devops Guide includes information on provisioning initial users when Synapse is first deployed (see Managing Users and Roles). This guide focuses on ongoing management of users and roles once Synapse admins have access to Storm (i.e., the Storm CLI or Optic UI).

Working with Users

Add a User

The auth.user.add command creates a new user. Newly created users do not have any permissions (other than those associated with the built-in all role).

Example:

Add the user “Ron” with email address ronthecat@vertex.link:

storm> auth.user.add ron --email [email protected]
User (ron) added with iden: f50bda9dac3e1dc3ad7c5ff1bcfcccad

Tip

Users are represented by a unique 128-bit identifier (iden). You can modify information about the user account (such as the username or associated email address) without affecting the underlying identifier or any associated roles or permissions.

Display a User

The auth.user.show command displays information about a user, including any assigned roles or rules (permissions) and their order.

Example:

Display information for user “Ron”:

storm> auth.user.show ron
User: ron (f50bda9dac3e1dc3ad7c5ff1bcfcccad)

  Locked: false
  Admin: false
  Email: [email protected]
  Rules:

  Roles:
    0bad4fd4cafc61c9d4f9b4cd349d3a0a - all

  Gates:

Modify a User

The auth.user.mod command modifies a user account. Use the command to:

  • Change the username or email address associated with the user.

  • Set or reset the user’s password.

  • Assign (or remove) admin status for the user.

  • Lock (or unlock) the account.

Examples:

Update the email address for user “Ron”:

storm> auth.user.mod ron --email [email protected]
User (ron) email address set to [email protected].

Assign admin status to the user “ron_admin”:

storm> auth.user.mod ron_admin --admin $lib.true
User (ron_admin) admin status set to true.

Remove admin status from user “ron_admin”:

storm> auth.user.mod ron_admin --admin $lib.false
User (ron_admin) admin status set to false.

Lock the user account “ron_admin”:

storm> auth.user.mod ron_admin --locked $lib.true
User (ron_admin) locked status set to true.

Warning

We strongly encourage you to lock (disable) accounts when necessary instead of deleting them. Changes to data in the Cortex (such as creating nodes, setting properties, or adding tags) are associated with the user account that made those changes. Deleting an account associated with past changes will prohibit you from identifying the user who made those changes.

If necesssary, user accounts can be deleted using the $lib.auth.users.del(iden) library, but there is no equivalent Storm command.

List All Users

The auth.user.list command lists all users in the Cortex.

Example:

List all users:

storm> auth.user.list
Users:
  ron
  root

Locked Users:
  ron_admin

Working with Roles

Add a Role

The auth.role.add command creates a new role. Newly created roles do not have any permissions or associated user accounts.

Example:

Add the new role “cattribution analyst”:

storm> auth.role.add "cattribution analyst"
Role (cattribution analyst) added with iden: a6bdca3111e744c49c4e1740830ed0bc

Tip

Roles are represented by a unique 128-bit identifier (iden). You can later change information about the role (such as the role name) without affecting the underlying role or any associated permissions or users.

Display a Role

The auth.role.show command displays information about a role, including any assigned rules (permissions) and their associated objects.

Example:

Display information for the “all” role:

storm> auth.role.show all
Role: all (0bad4fd4cafc61c9d4f9b4cd349d3a0a)

  Rules:

  Gates:
    01e8b563b30849d5f91dcce30c793b12 - (layer)
      [0  ] - layer.read
    b324aa45436c575bf6aa8aeba5313ed8 - (view)
      [0  ] - view.read

Modify a Role

The auth.role.mod command modifies a role. The command can be used to change the name of the role.

Example:

Change the name of the role “cattribution analyst” to “meow-ware analyst”:

storm> auth.role.mod "cattribution analyst" --name "meow-ware analyst"
Role (cattribution analyst) renamed to meow-ware analyst.

List all Roles

The auth.role.list command lists all roles in the Cortex.

Example:

List all roles:

storm> auth.role.list
Roles:
  a-cat-emic researcher
  all
  cattribution analyst
  meow-ware analyst

Delete a Role

The auth.role.del command deletes a role.

Example:

Delete the role “meow-ware analyst”:

storm> auth.role.del "meow-ware analyst"
Role (meow-ware analyst) deleted.

Note

Deleting a role has no impact on any users who have been granted the role (other than losing any permissions provided by that role). The user accounts remain intact and the role is simply removed from each user’s list of roles.

Grant or Revoke Roles

Granting a role to a user allows the user to inherit the role’s permissions. Revoking a role removes the associated permissions from the user. It is not possible to grant a role to another role (i.e., roles cannot be nested).

Roles can be granted or revoked using the auth.user.grant and auth.user.revoke commands.

Examples:

Grant the role “cattribution analyst” to the user “ron”:

storm> auth.user.grant ron "cattribution analyst"
Granting role cattribution analyst to user ron.

Revoke the role “a-cat-emic researcher” from user “ron”:

storm> auth.user.revoke ron "a-cat-emic researcher"
Revoking role a-cat-emic researcher from user ron.

Note

The order in which roles are granted to a user matters; when determining whether a user has permission to perform an action, the permissions for each of the user’s roles are checked in sequence.

Each role granted to a user is added to the end of the set of roles unless a location (index) for the role is specified. To “reorder” roles, you must either:

  • revoke the roles and grant them in the desired order;

  • use the --index option to specify the location to insert the role;

  • use setRoles(idens) to replace the user’s roles with a new list of roles; or

  • use the commercial Synapse UI (Optic) to reorder the roles using drag-and drop.

See Permissions Background for additional detail on permissions and Precedence.

Assign and Manage Permissions

Synapse provides a highly flexible system of role-based access control (RBAC). Rules are used to assign permissions to users and / or roles, with a defined order of precedence for how permissions are evaluated.

Permissions can be assigned very broadly, such as allowing a user (or role) to create / modify / delete any node. Permissions can also be very fine-grained, restricting users so that they can only create specific nodes, set specific properties, create specific edges, or apply specific tags.

Permissions Background

Before describing how to assign and manage permissions in Synapse, it is helpful to define some key components of Synapse and the permissions ecosystem.

Services

Synapse is designed as a modular set of services. A service can be thought of as a container used to run an application. Synapse services make up the core Synapse architecture, and include the Cortex (data store), Axon (file storage), and the commercial Optic UI. Services handle user authentication and authorization.

From a Synapse Admin perspective, you will primarily be concerned with managing user accounts and permissions to (and within) the Synapse Cortex.

Tip

When we talk about “Synapse users” or “permissions to Synapse” we are generally referring to user accounts and roles in a Cortex, and permissions to a Cortex and its associated objects.

Depending on your Synapse deployment, you may need to grant or manage permissions to additional Synapse services. See the sections on Optic Permissions and Power-Up Permissions for details.

Cortex

The Cortex is Synapse’s primary data store. Users and roles are created and managed in the Cortex, and most things for which users will need permissions apply to the Cortex and to the views, layers, and data (nodes, tags, etc.) that reside there.

Auth Gate

An Auth Gate (or “gate”, informally) is an object within a service (such as a Cortex) that may have its own set of permissions. A View and a Layer are both common examples of Auth Gates.

Auth Gates are represented by a 128-bit identifier (iden) that uniquely identifies the Auth Gate object itself. They also have an associated type to specify the kind of Auth Gate object (e.g., “view”). Some Auth Gates also support the use of “user friendly” names, though this is dependent on the type of Auth Gate and has no impact on the underlying iden or associated permissions.

Scope

Scope refers to the object to which a particular permission applies. For example, permissions granted on an Auth Gate (such as a view) are scoped to (or local to) that Auth Gate. Permissions granted at the Cortex level are global with respect to the Cortex.

Scope affects the order (precedence) in which permissions are evaluated.

Permission

A permission is a string that is used to control access. For example:

view.add

Tip

A list of most permissions available in a Cortex can be found under Cortex Permissions. You can also display the list in Synapse using the auth.list.perms command.

Most permission strings use a dotted (hierarchical) format; specifying a permission higher up in the hierarchy includes all permissions below it. For example, the permission view includes all of the following permissions: view.add, view.del, view.read, and view.set.

Permissions related to objects such as nodes or tags can optionally extend the permission string to be highly specific, referencing particular forms, properties, tags/tag trees, or light edges. This allows you to set highly granular permissions.

Granular permissions may be useful for organizations with specialized users or teams, where certain individuals are responsible for specific types of analysis (e.g., strategic analysis vs. tactical threat tracking) and should be the only users authorized to create, modify, and tag certain types of data.

Granular permissions can also be used to differentiate between senior and junior roles; for example, only senior analysts may be allowed to apply tags representing certain assessments (such as attribution).

Examples:

Description

Permission

Perform any action on any kind of node

(including deleting nodes and working with properties, tags,

edges, and node data)

node

Add any kind of node

(but not delete nodes, or work with properties, tags, edges, or

node data)

node.add

Only add inet:ipv4 nodes

(but not set properties, or work with tags or edges)

node.add.inet:ipv4

Only add (set) the :asn property of inet:ipv4 nodes

(but not create nodes or work with other properties, tags,

edges, etc.)

node.prop.set.inet:ipv4:asn

Add or remove any tag

(Note that adding/removing tags may require the ability to

create syn:tag nodes, unless those nodes already exist.)

node.tag

Only add and remove tags in the “mytag” tag tree

node.tag.add.mytag node.tag.del.mytag

Add or remove any edge

(Note that adding or removing edges allows creating edges

between any nodes; there are no model constraints on the

kinds of nodes that can be joined. It also allows the creation

of new / arbitrarily named edges.)

node.edge

Only add edges

node.edge.add

Only add refs edges

node.edge.add.refs

Note

Permissions strings do not support wildcards (*). For example, you cannot specify node.tag.*.mytag to allow users to both add and delete tags in the mytag tree.

Rule

A rule is used to grant (or prohibit) a specific permission. Rules are evaluated in a defined order of precedence.

When you specify a rule, there is an implicit allow directive; a permission string by itself indicates the permission is allowed/true:

view.add

To use a rule to deny a permission, use the “not” or “bang” symbol ( ! ) to indicate the permission is denied/false:

!node.tag.add.mytag

Precedence

Rules in Synapse are evaluated in order of precedence. A requested action will be allowed (or denied) based on the first matching rule found for the action. If no matching rule is found, the action is denied.

Generally speaking, rules are evaluated from “most specific” to “least specific”. Rules are evaluated in the following order:

  • User rules at the local (i.e., Auth Gate) level.

  • Role rules at the local level.

  • User rules at the global (i.e., Cortex) level.

  • Role rules at the global level.

Note

Because global rules are evaluated after local rules, permissions granted at the global level can “override” permissions that are not explicitly denied at the local level. For example, a user may fork a view (making them admin of that view) and grant “read” access to a coworker (view.read).

If the coworker has “write” permissions (such as node.tag) at the global level, they will be able to add tags within the forked view (or any view where they have view.read permissions).

If the user forking the view also specified !node for the view’s layer, the coworker would be prevented from adding any tags in the forked view (or making any edits whatsoever).

Roles (granted to a user) and rules (assigned to a user or role) are also ordered:

  • When granting roles to a user, each new role is added to the end of the list of roles unless a location (index) for the role is specified.

  • When assigning rules to a role or user, each new rule is added to the end of the list of rules unless a location (index) for the rule is specified.

Rules and roles are evaluated in the following order:

  • User rules are evaluated in order from first to last.

  • Each role granted to a user is evaluated in order from first to last.

  • For each role, the role’s rules are evaluated in order from first to last.

This means that the same rules, applied and evaluated in a different order, will give different results. As a simple example:

These rules will allow the creation of file:bytes nodes, but no other nodes:

node.add.file:bytes
!node.add

The same rules in the opposite order will disallow the creation of any nodes:

!node.add
node.add.file:bytes

Admin

Admin status allows a user to bypass all permissions checks for the scope where the user is admin. For example, a Synapse (Cortex) admin user can bypass all Cortex permissions checks (can “do anything” within the Cortex).

Users are generally admin of objects that they create. A user who forks a view is admin for the view that they fork, and can bypass all permissions checks (“do anything”) within the forked view.

Note

It is not possible to assign admin privileges to a role.

Easy Permissions

Easy permissions (“easy perms” for short) is a mechanism that simplifies granting common sets of permissions to users or roles for a particular object. Where easy perms are used, you can specify four levels of access: deny, read, edit, and admin. These access levels have corresponding integer values:

  • Deny = 0

  • Read = 1

  • Edit = 2

  • Admin = 3

Easy perms apply to specific objects. Where easy perms are available, the following conventions apply:

  • The user who creates the object has admin privileges for that object.

  • Admin privileges include the ability to grant permissions to others (including the ability to explicitly deny access).

  • Admin privileges are required to delete the object (i.e., edit permissions do not include delete).

Tip

$lib.macro.grant library is an example of where easy permissions can be used to assign permissions.

Views and Layers

Data in a Cortex is stored in one or more layers (see Layer). Layers are composed into views (see View) containing the data that should be visible to users or roles. (A standard installation of Synapse consists of the default view, which contains one layer.)

Views define the data that a user or role can see - they act as a read boundary. Granting the view.read permission on a view allows users to see (read) data in any of the view’s layers; you do not need to explicitly grant “read” access to the individual layers themselves.

The ability to read data in a view is “all or nothing” - you cannot allow users to see some nodes in a view but not others. (Sensitive data should be stored in its own layer, and views containing that layer should be limited to users or roles with a need to access that data.)

Layers define the changes (if any) that a user or role can make to data in Synapse - they act as a write boundary. In normal circumstances, only the top layer in a view is writable. The ability to write data to a layer is controlled by the various node.* permissions, which specify the forms / properties / tags / light edges a user or role can work with (create / modify / delete). Permissions to modify data must be assigned at the appropriate layer (or globally, if the permissions apply to all writable layers in the Cortex).

Assign Permissions

You assign (allow or deny) permissions in Synapse by adding rules to (or removing rules from) roles or users. Recall that order matters when adding rules (see Precedence).

From a Synapse Admin perspective, managing permissions within Synapse commonly involves:

  • Assigning rules to users and roles within the Cortex.

  • Assigning rules to users and roles for various Auth Gates (such as layers or views) if necessary.

  • Assigning rules to users and roles to allow or deny access to additional services, such as various Power-Ups.

Permissions in Synapse are managed using the Storm auth commands.

In the commercial Optic UI, permissions can also be managed through the Admin Tool and through dialogs associated with various objects (such as Views or Stories).

Tip

If a user attempts an action that they do not have permissions to perform, Synapse will return an AuthDeny error that lists the specific permission that is required.

Note

The descriptions and examples below assume that you have deployed Synapse using native Synapse management and authentication of users, roles, and permissions.

Default Permissions

Synapse includes the following default permissions:

  • The built-in root user has admin access (admin=true) to the Cortex.

  • The built-in all role has read access (view.read) to any view created with worldreadable=True. This includes the default view.

Any additional permissions must be explicitly granted to users or roles. In all but a few edge cases, Synapse assumes an implicit default deny all as the final rule evaluated when checking permissions.

Note

There are a few edge cases where a specific permission assumes a default allow instead of a default deny, but these are uncommon. These cases are highly specific, and usually arise in cases where a new permission has been implemented. That is, an action that was not originally subject to a permissions check now has one (usually because of a need to explicitly deny that action to particular users or roles).

If a previously unchecked action were added with “default deny”, it would potentially break existing Synapse deployments by suddenly blocking an action that had been previously allowed (ungated). In these circumstances the new permission is given a “default allow” that can then be specifically denied if necessary.

Available Permissions

The auth.perms.list command can be used to display the set of permissions available in your Cortex. This includes native Synapse permissions as well as any permissions associated with other packages and services.

Sample output for this command can be seen under Cortex Permissions. The permissions available on your Cortex may vary depending on the services and packages installed (e.g., such as Power-Ups).

Global (Cortex) Permissions

Permissions in Synapse can be assigned at the global (Cortex) level, or to a specific Auth Gate (see Auth Gate Permissions). To assign permissions to an Auth Gate, you must specify its identifier (iden) (i.e., using the --gate option to the appropriate Storm command) when adding the associated rule to a user or role.

If you do not specify an Auth Gate, the permissions are global and apply to any / all instances within the Cortex where a user or role has access. For example, the following Storm command:

auth.role.addrule all node

…grants (allows) the node permission to the built-in all role. This allows any user (because all users are granted the all role by default) to perform any action on any node in any layer that is the topmost (writeable) layer in any view that the user can see.

Specifying rules at the global (Cortex) level may be sufficient for many basic Synapse deployments.

Note

Recall that order matters when adding rules:

  • by default, each rule is added to the end of the list of rules assigned to a user or role; and

  • rules are evaluated in order of precedence.

To reorder rules, you must:

  • use the --index option with auth.user.addrule or auth.role.addrule to specify a location to insert a specific rule;

  • remove and re-add the rules in the desired order;

  • use setRules(rules, gateiden=$lib.null) or setRules(rules, gateiden=$lib.null) to replace the rules for a user or role with a new set of rules; or

  • use the commercial Synapse UI (Optic) to reorder rules using drag-and-drop.

Assign Permissions

Permissions rules (allow or deny) are assigned using the auth.user.addrule and auth.role.addrule commands.

Examples:

Prevent the user “ron” from setting tag descriptions (setting the syn:tag:desc property):

storm> auth.user.addrule ron "!node.prop.set.syn:tag:desc"
Added rule !node.prop.set.syn:tag:desc to user ron.

Tip

Deny rules specified with Storm must be enclosed in quotes (single or double) because they begin with a symbol ( ! ).

Allow the role “senior analysts” to add tags in threat attribution (cno.threat) tag tree:

storm> auth.role.addrule "senior analysts" node.tag.add.cno.threat
Added rule node.tag.add.cno.threat to role senior analysts.

Prevent the “all” role from deleting nodes:

storm> auth.role.addrule all "!node.del"
Added rule !node.del to role all.

Prevent the “all” role from deleting nodes, and insert this as the first rule for the role:

storm> auth.role.addrule --index 0 all "!node.del"
Added rule !node.del to role all.

Tip

Recall that you can Display a User or Display a Role with the auth.user.show and auth.role.show commands.

Revoke Permissions

Permissions rules are revoked using the auth.user.delrule and auth.role.delrule commands.

Examples:

Revoke the rule that prevents user “ron” from setting tag descriptions:

storm> auth.user.delrule ron "!node.prop.set.syn:tag:desc"
Removed rule !node.prop.set.syn:tag:desc from user ron.

Revoke the rule that allows “junior analysts” to apply tags in the cno.threat tag tree:

storm> auth.role.delrule "junior analysts" node.tag.cno.threat
Removed rule node.tag.cno.threat from role junior analysts.
Check Permissions

The auth.user.allowed command can be used to check whether a user has a particular permission (i.e., is allowed to perform the associated operation) for a specific scope (i.e., globally or for an individual Auth Gate). If an appropriate allow rule exists, the command will show the source (i.e., the rule, role, and / or associated Auth Gate) where the permission has been assigned.

Tip

  • A user may have permissions locally (e.g., to a specific Auth Gate) that they do not have globally. In other words a global check may (correctly) show that a user does not have an expected permission globally, but the permission will show as “allowed” when the appropriate Auth Gate is checked.

  • When checking whether a user can see (read) data or manipulate (e.g., fork) a view, check the relevant view.

  • When checking whether a user can modify (write or delete) data, check the relevant layer.

Examples:

Check whether user ‘ron’ is allowed to apply tags in the cno tag tree globally:

storm> auth.user.allowed ron node.tag.add.cno
allowed: true - Matched role rule (node.tag.add.cno) for role cattribution analyst.

Check whether user ‘ron’ is allowed to apply tags in the cno tag tree in the current layer:

storm> auth.user.allowed --gate $lib.layer.get().iden ron node.tag.add.cno
allowed: true - Matched role rule (node.tag.add.cno) for role cattribution analyst.

Note that the response for each of the commands above is identical, even though the first example performed a global check (no --gate option) while the second example checked the current layer (retrieved with $lib.layer.get()). The response in the second example shows that Ron can apply tags in the current layer because he has global permissions for this action - indicated by the absence of an iden in the response. If Ron’s permissions were restricted to the queried gate (in this case, the layer), the associated iden would have been included in the command output.

Check whether user ‘ron’ is allowed to fork the current view:

storm> auth.user.allowed --gate $lib.view.get().iden ron view.add
allowed: false - No matching rule found.

Auth Gate Permissions

To assign permissions for an Auth Gate, you use the same Storm commands used to assign global permissions, but you must specify the Auth Gate’s full identifier (iden) (using the --gate option) when adding or removing the rule.

Obtain a Gate’s Iden

The Storm view and layer commands can be used to manage views and layers, respectively. In particular, the following commands are useful for displaying all views or layers (including their idens), or displaying a specific view or layer:

Examples:

Display all views:

storm> view.list

View: b324aa45436c575bf6aa8aeba5313ed8 (name: default)
  Creator: 2f72aba02356f6f966fdef860477247f
  Layers:
    01e8b563b30849d5f91dcce30c793b12: default readonly: False

Display the current layer:

storm> layer.get
Layer: 01e8b563b30849d5f91dcce30c793b12 (name: default) readonly: False creator: 2f72aba02356f6f966fdef860477247f
View a Gate’s Permissions

The auth.gate.show command is used to display permissions information about a particular Auth Gate (e.g., a view or layer). You can provide the specific iden for an Auth Gate, or use the syntax below to retrieve information for the current view or layer. (Viewing information for the “current layer” will return information for the top layer of the current view.)

Example:

Display information for the current view:

storm> auth.gate.show $lib.view.get().iden
Gate Type: view

Auth Gate Users:
  2f72aba02356f6f966fdef860477247f - root
    Admin: true
    Rules:

Auth Gate Roles:
  0bad4fd4cafc61c9d4f9b4cd349d3a0a - all
    Rules:
      [0  ] - view.read

Display information for the current layer (i.e., the top layer of the current view):

storm> auth.gate.show $lib.layer.get().iden
Gate Type: layer

Auth Gate Users:
  2f72aba02356f6f966fdef860477247f - root
    Admin: true
    Rules:

Auth Gate Roles:
  0bad4fd4cafc61c9d4f9b4cd349d3a0a - all
    Rules:
      [0  ] - layer.read

Permissions Best Practices

  • Synapse Admins should use a designated admin account for administrative tasks and a separate account for their user tasks.

  • Where possible, assign permissions to roles and grant roles to users vs. assigning permissions to users directly.

  • Create a general purpose role (such as users, or use the built-in all role) and assign the basic permissions that all Synapse users should have to this role. This includes “things all users should be able to do” (allow rules) as well as “things all users should be explicitly prohibited from doing” (deny rules). Create additional roles as needed to allow (or further restrict) specific operations.

  • Segregate data with different access requirements into different layers. Grant access to data sets by composing those layers into views and granting roles access to the appropriate view(s).

  • The ability to delete nodes in Synapse should be granted to a limited number of trusted individuals. We recommend creating a dedicated role for this purpose.

  • If a role will have limited permissions, it is generally easier to explicitly allow only those actions; everything else will be denied by default.

  • If a role or user will have broad permissions with some restrictions, it is generally easier to explicitly deny the restricted actions first, and then grant broad permissions (for example !node.del followed by node). Because permissions rules are checked in order, Synapse will encounter any deny rules first (i.e., user is unable to delete nodes), blocking the prohibited action while then allowing anything not specifically denied (i.e., user can do anything else to nodes).

Example Permissions

The examples below illustrate a few common use cases for roles and permissions within Synapse. These rule sets are meant as simple illustrations and do not necessarily illustrate fully-defined, production-ready permission sets.

Recall that:

  • Views control read access to the data store. Users with read access to a view (view.read) can read all data in all layers of the view (i.e., no additional layer-specific permissions are required for read access).

  • Layers control write access to the data store. Use permissions to manage the data that can be written to a given layer (including the ability to merge data into that layer from a forked view).

  • A user who can fork a view is admin within their forked view.

A list of available Cortex permissions is available under the Cortex Permissions section, or can be viewed in Synapse with the auth.perms.list command.

Case 1 - Grant common permissions - basic

These basic permissions can be assigned to a role to allow users to perform common operations in Synapse.

Permission

Description

view.read

See / read any view

view.add

Fork any view they can see

node

Create, modify, or delete any type of data (nodes, properties, light

edges, tags, and node data) in the top layer of any view they can see

Tips:

  • The all role has implicit (and non-revocable) “read” access to Synapse’s default view. This is not the same as global view.read access. To allow the all role (or any role) to see other views, you must explicitly assign the view.read permission (either globally or to individual views).

  • Users can only fork (view.add) views they can see (view.read). If users should be allowed to fork any view where they have read access, the view.add permission can be assigned globally even if read access is managed on a per-view basis.

Case 2 - Grant common permissions - intermediate

These permissions expand on Case 1, but only allow the role to see specific views (by granting view.read locally to individual views).

Any global permissions (e.g., node.add) will apply to the top (writeable) layer of any view the role can see, unless the permissions are overridden locally.

These permissions also prevent the role from deleting nodes globally, while allowing them to delete properties or edges and to remove tags.

Permission

Scope

Description

view.add

global

Fork any view they can see (based on view.read)

!node.del

global

Prevent deletion of any nodes

node.add

global

Create nodes in the top layer of any view they can see

node.prop

global

Set, modify, or delete node properties in the top layer of any

view they can see

node.edge

global

Add or remove light edges in the top layer of any view they

can see

node.tag

global

Add or remove tags from nodes in the top layer of any view they

can see

view.read

local

See all the data in all the layers of the specific view(s)

where the rule is assigned

Case 3 - Create a dedicated role that can delete nodes

Deleting nodes indiscriminately or incorrectly can negatively impact your data store (i.e., leaving “holes” in the graph or destroying data). Synapse requires that users run an explicit command (delnode) to delete nodes, so the action is a deliberate choice (vs. an “accidental click”).

We strongly recommend that you create a role whose sole permission is the ability to delete nodes, and grant that role to a limited number of users. To do this:

  • Explicitly deny permission to delete nodes (!node.del) at the global level to the general purpose role you use to manage permissions for all users (as shown in Case 2 above).

  • Create a dedicated role whose only permission will be the ability to delete nodes.

    • We encourage a name that inspires caution, such as fire ze missiles or agents of destruction, but you can just use deleters.

  • Assign the node.del rule to the role (globally, or for specific layers).

Tips:

  • All delete operations (whether deleting nodes, properties, edges, or removing tags) must be performed directly in the layer where the data resides. As admin of any view that they fork, “normal” users can delete data created or modified within their forked view.

Case 4 - Place guardrails around writing (creating or merging) data

Permissions can be used to prevent roles from:

  • creating various types of data directly in a layer/view; or

  • merging various types of data into an underlying view (technically, to the view’s top layer).

These types of permissions can help ensure that data in a “production” layer remains as pristine and error-free as possible. For example:

  • Help to limit typos that result in “bad” tags or edges.

  • Prevent data from a sensitive or restricted layer from being written to a non-restricted layer.

Example use cases:

  • Use permissions around light edges to only allow the creation of specific named edges. This can limit typos in edge names and/or prevent users from creating arbitrarily named edges.

  • Use permissions around tags or tag trees to only allow applying certain tags (e.g., to enforce your organization’s tag conventions). For example, permissions can ensure that users’ “scratch” tags (#thesilence.mywork) or tags indicating sensitive data (#tlp.red) are not added to “production” data.

  • Use permissions around individual properties to prohibit setting specific properties in particular layers. For example, taxonomy properties (such as risk:threat:type) may be “under development” in an internal analysis view while users test and agree on appropriate categories. You may want to prevent this property from being set (merged) into production data until the taxonomy is finalized.

Tip

The degree to which you enforce data and tag conventions through permissions vs. by consensus (i.e., users agree on “best efforts” to keep the data tidy) will depend on your organization and your use case. Managing permissions adds overhead, but may be worth the effort for data sets that require high fidelity or quality. The overhead may have less benefit for internal data or test data where occasional errors have minimal impact and can be “cleaned up” as needed.

The sample rules below can be applied globally (a user with this role can write “approved” data to any writeable layer of any view they can see) or locally to specific layers.

The examples below only illustrate how certain write actions can be restricted and do not address other permissions that a user/role might need. These permissions could be added to an existing role (such as your general users role), or granted via their own role.

Example 1:

If a limited set of actions are allowed, simply specify the changes that the role can make. Anything else is implicitly denied by default.

In this example, a role with the following permissions can:

  • only add and remove tags in the listed tag trees; and

  • only create and delete the listed edges.

Permission

Description

node.tag.add.cno

Add / apply tags in the cno tree (e.g., cno, cno.mal,

cno.mal.plugx etc.)

node.tag.del.cno

Remove any tags in the cno tree

node.tag.add.rep

Add / apply any tags in the rep tree

node.tag.del.rep

Remove any tags in the rep tree

node.edge.add.refs

Add refs light edges

node.edge.del.refs

Delete refs light edges

node.edge.add.uses

Add uses light edges

node.edge.del.uses

Delete uses light edges

node.edge.add.targets

Add targets light edges

node.edge.del.targets

Delete targets light edges

Example 2:

If specific actions are prohibited, deny those changes and then allow “everything else”.

A role with the following permissions is prohibited from:

  • Creating risk:threat:type:taxonomy nodes (representing “categories” of threats).

  • Setting the :type property for risk:threat nodes (e.g., specifying the taxonomy category for a particular threat).

  • Creating tags in the tlp tree.

Note that the permissions as listed only prohibit actions. For a role with these permissions to be able to make other changes (e.g., add other nodes or edges), those permissions need to be granted after these “deny” rules, or as part of another role.

Permission

Description

!node.add.risk:threat:type:taxonomy

Prevent creating these nodes

!node.prop.set.risk:threat:type

Prevent setting this property (i.e., on existing

risk:threat nodes)

!node.tag.add.tlp

Prevent applying tags in the tlp tree

Tip

To prevent users or roles from making any changes to a particular view (i.e., users cannot merge any data into the view / write any data directly to the view’s topmost layer):

  • Do not add node permissions to the view’s topmost layer (write permissions that are not granted are implicitly denied).

  • If a role has been granted node (or similar) permissions globally, override this by explicitly denying (!node) the permission on the layer you want to protect.

Case 5 - Senior vs. junior roles

Senior roles (with more permissions) and junior roles (with limited permissions) are used in a variety of situations, such as new trainees vs. experienced users or junior vs. senior analysts.

When using a “fork and merge” workflow, a junior user can “do anything” (as admin) in a view that they fork. This allows them to enrich data and annotate their assessments using tags. But permissions can prevent them from merging some (or all) data and tags until a senior user has reviewed the changes. The senior role (with appropriate permissions) can then merge the data on the junior user’s behalf.

For example, tags representing key analytical assessments - such as determining if a file or indicator is associated with a malware family, or tags representing threat clustering and attribution - may require careful consideration. The ability to merge these tags may be limited to senior analysts who can verify that the junior analyst has applied them correctly.

These types of permissions are typically cumulative; generic users may be prohibited (or simply not allowed) to perform a certain action, with additional permissions granted to increasingly senior or experienced roles. In the example below, all users would have the general users role and analysts would be granted each additional role as they gained experience.

Example:

Role

Permission(s)

Description

users

!node.tag.cno

!node.tag.rep

node.tag

Prevent applying tags in the cno and

rep trees (representing specific analytical

assessements) but apply other tags

novice analyst

node.tag.add.rep

Novices can apply tags in the rep tree

(representing third-party reporting)

junior analyst

node.tag.add.cno.infra

Junior analysts can apply tags in the

cno.infra tree (related to network

infrastructure)

senior analyst

node.tag.add.cno.threat

node.tag.add.cno.mal

Senior analysts can apply tags in the

cno.threat and cno.mal trees

(assessments related to threat clusters and

malware families)

Note

Because of Precedence, as additional roles are granted, they would need to be added (indexed) before the users role to prevent that role’s explicit deny permissions from overriding the newly allowed tag privileges.

Case 6 - Specialized roles

For organizations with diverse analysis teams (e.g., where analysts specialize in particular areas) or organizations where multiple teams or departments use Synapse for different purposes, it may be helpful to create highly specialized roles.

Examples:

  • An organization with a dedicated malware analysis team may only allow those specialists to apply tags related to malware/code families and malware ecosystems.

  • An organization’s strategic analysts may be solely responsible for certain objects and related data. For example, a strategic team may be in charge of researching and creating organizations (ou:org) and associated industries (ou:industry) in order to track victimology. Strategic analysts can ensure that these objects are created according to the team’s standards and that organizations are assigned to the appropriate industries.

Malware analyst example:

  • We assume the ability to apply the specialized tags listed below is either not granted or explicitly denied elsewhere/to other roles.

  • Malware analysts can also be granted the ability to remove the tags listed below with the corresponding node.tag.del permissions.

Permission

Description

node.tag.add.cno.code

Apply cno.code tags (designating specific samples of code

families - e.g., cno.code.plugx)

node.tag.add.cno.mal

Apply cno.mal tags (designating components of malware / code

family ecosystems, such as related droppers or C2 - e.g.,

cno.mal.plugx)

node.tag.add.cno.rel

Apply cno.rel tags (designating components that may be observed

as part of a malware ecosystem but are not inherently malicious -

e.g., cno.rel.plugx)

Strategic analyst example:

  • We assume the ability to create these nodes / set these properties is either not granted or explicitly denied elsewhere/to other roles.

  • Strategic analysts can optionally be granted the ability to delete relevant nodes/properties with the corresponding node.del or node.prop.del permissions.

  • Depending on how you assign permissions, keep in mind that roles that cannot create nodes may still be able to set or modify properties on the node as long as the node already exists. This ability can be restricted via additional node.prop.set rules if necessary.

Permission

Description

node.add.ou:org

Create organization nodes

node.prop.set.ou:org:industries

Assign organizations to one or more industries

node.add.ou:industry

Create industry nodes

Cortex Permissions

The following is a list of the Cortex permissions that may be granted to a user or role. If a gate other than cortex is specified, the permission will be checked against the specific gate instance and if no match is found, it will be checked against the global rules.

storm> auth.perms.list
auth.role.set.name
    Permits a user to change the name of a role.
    gate: cortex
    default: false

auth.role.set.rules
    Permits a user to modify rules of a role.
    gate: cortex
    default: false

auth.self.set.apikey
    Permits a user to manage their API keys.
    gate: cortex
    default: true

auth.self.set.email
    Permits a user to change their own email address.
    gate: cortex
    default: true

auth.self.set.name
    Permits a user to change their own username.
    gate: cortex
    default: true

auth.self.set.passwd
    Permits a user to change their own password.
    gate: cortex
    default: true

auth.user.get.profile.<name>
    Permits a user to retrieve their profile information.
    gate: cortex
    default: false
    example: auth.user.get.profile.fullname

auth.user.grant
    Controls granting roles to a user.
    gate: cortex
    default: false

auth.user.pop.profile.<name>
    Permits a user to remove profile information.
    gate: cortex
    default: false
    example: auth.user.pop.profile.fullname

auth.user.revoke
    Controls revoking roles from a user.
    gate: cortex
    default: false

auth.user.set.admin
    Controls setting/removing a user's admin status.
    gate: cortex
    default: false

auth.user.set.apikey
    Permits a user to manage API keys for other users. USE WITH CAUTUON!
    gate: cortex
    default: false

auth.user.set.email
    Controls changing a user's email address.
    gate: cortex
    default: false

auth.user.set.locked
    Controls locking/unlocking a user account.
    gate: cortex
    default: false

auth.user.set.passwd
    Controls changing a user password.
    gate: cortex
    default: false

auth.user.set.profile.<name>
    Permits a user to set profile information.
    gate: cortex
    default: false
    example: auth.user.set.profile.fullname

auth.user.set.rules
    Controls adding rules to a user.
    gate: cortex
    default: false

axon.del
    Controls the ability to remove a file from the Axon.
    gate: cortex
    default: false

axon.get
    Controls the ability to retrieve a file from the Axon.
    gate: cortex
    default: false

axon.has
    Controls the ability to check if the Axon contains a file.
    gate: cortex
    default: false

axon.upload
    Controls the ability to upload a file to the Axon.
    gate: cortex
    default: false

backup.del
    Permits a user to delete an existing backup.
    gate: cortex
    default: false

backup.list
    Permits a user to list existing backups.
    gate: cortex
    default: false

backup.run
    Permits a user to create a backup.
    gate: cortex
    default: false

cron.add
    Permits a user to create a cron job.
    gate: view
    default: false

cron.del
    Permits a user to remove a cron job.
    gate: cronjob
    default: false

cron.get
    Permits a user to list cron jobs.
    gate: cronjob
    default: false

cron.set
    Permits a user to modify/move a cron job.
    gate: cronjob
    default: false

cron.set.creator
    Permits a user to modify the creator property of a cron job.
    gate: cortex
    default: false

globals
    Used to control all operations for global variables.
    gate: cortex
    default: false

globals.get
    Used to control read access to all global variables.
    gate: cortex
    default: false

globals.get.<name>
    Used to control read access to a specific global variable.
    gate: cortex
    default: false

globals.pop
    Used to control delete access to all global variables.
    gate: cortex
    default: false

globals.pop.<name>
    Used to control delete access to a specific global variable.
    gate: cortex
    default: false

globals.set
    Used to control edit access to all global variables.
    gate: cortex
    default: false

globals.set.<name>
    Used to control edit access to a specific global variable.
    gate: cortex
    default: false

model.form.add
    Controls access to adding extended model forms.
    gate: cortex
    default: false

model.form.add.<form>
    Controls access to adding specific extended model forms.
    gate: cortex
    default: false
    example: model.form.add._foo:bar

model.form.del
    Controls access to deleting extended model forms.
    gate: cortex
    default: false

model.form.del.<form>
    Controls access to deleting specific extended model forms.
    gate: cortex
    default: false
    example: model.form.del._foo:bar

model.prop.add
    Controls access to adding extended model properties.
    gate: cortex
    default: false

model.prop.add.<form>
    Controls access to adding specific extended model properties.
    gate: cortex
    default: false
    example: model.prop.add._foo:bar

model.prop.del
    Controls access to deleting extended model properties.
    gate: cortex
    default: false

model.prop.del.<form>
    Controls access to deleting specific extended model properties.
    gate: cortex
    default: false
    example: model.prop.del._foo:bar

model.tagprop.add
    Controls access to adding extended model tag properties.
    gate: cortex
    default: false

model.tagprop.del
    Controls access to deleting extended model tag properties.
    gate: cortex
    default: false

model.univ.add
    Controls access to adding extended model universal properties.
    gate: cortex
    default: false

model.univ.del
    Controls access to deleting extended model universal properties.
    gate: cortex
    default: false

node
    Controls all node edits in a layer.
    gate: layer
    default: false

node.add
    Controls adding any form of node in a layer.
    gate: layer
    default: false

node.add.<form>
    Controls adding a specific form of node in a layer.
    gate: layer
    default: false
    example: node.add.inet:ipv4

node.del
    Controls removing any form of node in a layer.
    gate: layer
    default: false

node.del.<form>
    Controls removing a specific form of node in a layer.
    gate: layer
    default: false

node.prop
    Controls editing any prop on any node in the layer.
    gate: layer
    default: false

node.prop.del
    Controls removing any prop on any node in a layer.
    gate: layer
    default: false

node.prop.del.<form>
    Controls removing any property from a form of node in a layer.
    gate: layer
    default: false
    example: node.prop.del.inet:ipv4

node.prop.del.<form>.<prop>
    Controls removing a specific property from a form of node in a layer.
    gate: layer
    default: false
    example: node.prop.del.inet:ipv4.asn

node.prop.set
    Controls setting any prop on any node in a layer.
    gate: layer
    default: false

node.prop.set.<form>
    Controls setting any property on a form of node in a layer.
    gate: layer
    default: false
    example: node.prop.set.inet:ipv4

node.prop.set.<form>.<prop>
    Controls setting a specific property on a form of node in a layer.
    gate: layer
    default: false
    example: node.prop.set.inet:ipv4.asn

node.tag
    Controls editing any tag on any node in a layer.
    gate: layer
    default: false

node.tag.add
    Controls adding any tag on any node in a layer.
    gate: layer
    default: false

node.tag.add.<tag...>
    Controls adding a specific tag on any node in a layer.
    gate: layer
    default: false
    example: node.tag.add.cno.mal.redtree

node.tag.del
    Controls removing any tag on any node in a layer.
    gate: layer
    default: false

node.tag.del.<tag...>
    Controls removing a specific tag on any node in a layer.
    gate: layer
    default: false
    example: node.tag.del.cno.mal.redtree

pkg.add
    Controls access to adding storm packages.
    gate: cortex
    default: false

pkg.del
    Controls access to deleting storm packages.
    gate: cortex
    default: false

service.add
    Controls the ability to add a Storm Service to the Cortex.
    gate: cortex
    default: false

service.del
    Controls the ability to delete a Storm Service from the Cortex
    gate: cortex
    default: false

service.get
    Controls the ability to get the Service object for any Storm Service.
    gate: cortex
    default: false

service.get.<iden>
    Controls the ability to get the Service object for a Storm Service by iden.
    gate: cortex
    default: false

service.list
    Controls the ability to list all available Storm Services and their service definitions.
    gate: cortex
    default: false

storm.asroot.cmd.<cmdname>
    Controls running storm commands requiring root privileges.
    gate: cortex
    default: false
    example: storm.asroot.cmd.movetag

storm.asroot.mod.<modname>
    Controls importing modules requiring root privileges.
    gate: cortex
    default: false
    example: storm.asroot.cmd.synapse-misp.privsep

storm.graph.add
    Controls access to add a storm graph.
    gate: cortex
    default: true

storm.inet.imap.connect
    Controls connecting to external servers via imap.
    gate: cortex
    default: false

storm.inet.smtp.send
    Controls sending SMTP messages to external servers.
    gate: cortex
    default: false

storm.lib.auth.roles.add
    Controls the ability to add a role to the system. USE WITH CAUTION!
    gate: cortex
    default: false

storm.lib.auth.roles.del
    Controls the ability to remove a role from the system. USE WITH CAUTION!
    gate: cortex
    default: false

storm.lib.auth.users.add
    Controls the ability to add a user to the system. USE WITH CAUTION!
    gate: cortex
    default: false

storm.lib.auth.users.del
    Controls the ability to remove a user from the system. USE WITH CAUTION!
    gate: cortex
    default: false

storm.lib.axon.del
    Controls the ability to remove a file from the Axon.
    gate: cortex
    default: false

storm.lib.axon.get
    Controls the ability to retrieve a file from the Axon.
    gate: cortex
    default: false

storm.lib.axon.has
    Controls the ability to check if the Axon contains a file.
    gate: cortex
    default: false

storm.lib.axon.wget
    Controls the ability to retrieve a file from URL and store it in the Axon.
    gate: cortex
    default: false

storm.lib.axon.wput
    Controls the ability to push a file from the Axon to a URL.
    gate: cortex
    default: false

storm.lib.cortex.httpapi.add
    Controls the ability to add a new Extended HTTP API on the Cortex.
    gate: cortex
    default: false

storm.lib.cortex.httpapi.del
    Controls the ability to delete an Extended HTTP API on the Cortex.
    gate: cortex
    default: false

storm.lib.cortex.httpapi.get
    Controls the ability to get or list Extended HTTP APIs on the Cortex.
    gate: cortex
    default: false

storm.lib.cortex.httpapi.set
    Controls the ability to modify an Extended HTTP API on the Cortex.
    gate: cortex
    default: false

storm.lib.inet.http.proxy
    Permits a user to specify the proxy used with `$lib.inet.http` APIs.
    gate: cortex
    default: false

storm.lib.log.debug
    Controls the ability to log a debug level message.
    gate: cortex
    default: false

storm.lib.log.error
    Controls the ability to log a error level message.
    gate: cortex
    default: false

storm.lib.log.info
    Controls the ability to log a info level message.
    gate: cortex
    default: false

storm.lib.log.warning
    Controls the ability to log a warning level message.
    gate: cortex
    default: false

storm.lib.telepath.open
    Controls the ability to open an arbitrary telepath URL. USE WITH CAUTION.
    gate: cortex
    default: false

storm.lib.telepath.open.<scheme>
    Controls the ability to open a telepath URL with a specific URI scheme. USE WITH CAUTION.
    gate: cortex
    default: false

storm.macro.add
    Controls access to add a storm macro.
    gate: cortex
    default: true

storm.macro.admin
    Controls access to edit/set/delete a storm macro.
    gate: cortex
    default: false

storm.macro.edit
    Controls access to edit a storm macro.
    gate: cortex
    default: false

trigger.add
    Controls adding triggers.
    gate: cortex
    default: false

trigger.del
    Controls deleting triggers.
    gate: view
    default: false

trigger.get
    Controls listing/retrieving triggers.
    gate: trigger
    default: false

trigger.set
    Controls enabling, disabling, and modifying the query of a trigger.
    gate: view
    default: false

trigger.set.<property>
    Controls modifying specific trigger properties.
    gate: view
    default: false

trigger.set.doc
    Controls modifying the doc property of triggers.
    gate: trigger
    default: false

trigger.set.name
    Controls modifying the name property of triggers.
    gate: trigger
    default: false

trigger.set.user
    Controls modifying the user property of triggers.
    gate: cortex
    default: false

view
    Controls all view permissions.
    gate: cortex
    default: false

view.add
    Controls access to add a new view including forks.
    gate: cortex
    default: false

view.del
    Controls access to delete a view.
    gate: view
    default: false

view.fork
    Controls access to fork a view.
    gate: view
    default: true

view.read
    Controls read access to view.
    gate: view
    default: false

view.set.<setting>
    Controls access to change view settings.
    gate: view
    default: false
    example: view.set.name

Optic Permissions

Commercial Synapse customers with the Optic UI may need to explicitly grant users or roles permission to some UI tools (such as Spotlight).

Tip

You do not need to explicitly grant permissions to Optic itself. If you are creating and managing Synapse (“Cortex”) users and roles via Optic, they have permission to access Optic by default.

Power-Up Permissions

Synapse Power-Ups have their own sets of permissions that must be granted to users or roles to allow them to use the Power-Up and any associated Storm commands. Specific permissions are documented in the Admin Guide section of the Power-Up documentation for the individual Power-Up.

Tip

While most Vertex-provided Power-Ups are part of the commercial Synapse offering, the following Rapid Power-Ups are also available for use with the community (open source) version of Synapse:

Storm Runtime Permissions

When a user runs a Storm query interactively (e.g., in the Storm CLI or via the Optic Query Bar), or performs an action in the Optic UI (such as accessing a menu option), the query or action executes with the permissions of the user, based on the applicable user and role permissions and the current scope for the query or action.

There are a few cases of Storm runtime execution where different permissions are used that may require additional considerations.

Automation

Synapse includes the ability to automate Storm-based tasks using triggers, cron jobs, and / or macros. These elements are all impacted by permissions in various ways, including:

  • who can create or manage automation (e.g., by default any user can create a macro, but explicit permissions are required to create triggers or cron jobs);

  • who a given piece of automation runs as (e.g., macros run as the user who executes them, but triggers and cron jobs run as the user who created them).

Refer to the Storm Reference - Automation section of the Synapse User Guide for a detailed discussion of automation in Synapse (including permissions considerations).

Power-Ups

Power-Ups implement Storm packages and Storm services to provide additional functionality to Synapse. Power-Ups may be provided by The Vertex Project (as free or commercial offerings). Organizations may also develop their own custom Power-Ups.

Power-Ups commonly install Storm commands to allow users to make use of the additional capabilities of the Power-Up. In some cases, Power-Ups may need to access sensitive data (such as API keys or similar credentials) or perform actions (e.g., in adding nodes or applying tags) that some users would not be allowed to perform on their own.

Power-Ups can use privilege separation (“privsep”) so that a limited subset of Power-Up capabilities can run with elevated privileges if necessary, with the remainder of the code running as the user who calls the Power-Up.

See the Rapid Power-Up Development section of the Synapse Developer Guide for additional details.

Note

Synapse Admins are typically only responsible for ensuring that the appropriate users and roles can use or run individual Power-Ups (see Power-Up Permissions). While Synapse Admins should be aware of privilege separation within a Power-Up as a best practice, implementation of privilege separation is left to Power-Up developers.

Add Extended Model Elements

The Synapse data model in a Cortex can be extended with custom forms or properties by using the model extension Storm Library ($lib.model.ext). Extended model forms and properties must have names beginning with an underscore (_) to avoid potential naming conflicts with built-in model elements.

Note

Extended model elements that are in-use (have nodes using the extended forms or properties) cannot be removed until all instances of that extended model element are removed. In other words, before removing extended forms any nodes created with that extended form must be delete first, and before removing extended properties any nodes with that extended property must have the property value removed.

Extended Forms

When adding a form, $lib.model.ext.addForm takes the following arguments:

formname

Name of the form, must begin with an underscore (_) and contain at least one colon (:).

basetype

The Synapse data model type for the form.

typeopts

A dictionary of type specific options.

typeinfo

A dictionary of info values for the form.

To add a new form named _foocorp:name, which contains string values which will be normalized to lowercase, with whitespace stripped from the beginning/end:

$typeopts = ({'lower': $lib.true, 'strip': $lib.true})
$typeinfo = ({'doc': 'Foocorp name.'})

$lib.model.ext.addForm(_foocorp:name, str, $typeopts, $typeinfo)

If the form is no longer in use and there are no nodes of this form in the Cortex, it can be removed with:

$lib.model.ext.delForm(_foocorp:name)

Extended Properties

When adding properties, $lib.model.ext.addFormProp takes the following arguments:

formname

Name of the form to add the property to, may be a built-in or extended model form.

propname

Relative name of the property, must begin with an underscore (_).

typedef

A tuple of (type, typeopts) which defines the type for the property

propinfo

A dictionary of info values for the property.

To add a property named _score to the _foocorp:name form which contains int values between 0 and 100:

$typeopts = ({'min': 0, 'max': 100})
$propinfo = ({'doc': 'Score for this name.'})

$lib.model.ext.addFormProp(_foocorp:name, _score, (int, $typeopts), $propinfo)

To add a property named _aliases to the _foocorp:name form which contains a unique array of ou:name values:

$typeopts = ({'type': 'ou:name', 'uniq': $lib.true})
$propinfo = ({'doc': 'Aliases for this name.'})

$lib.model.ext.addFormProp(_foocorp:name, _aliases, (array, $typeopts), $propinfo)

Properties may also be added to existing forms, for example, to add a property named _classification to inet:fqdn which must contain a string from a predefined set of values:

$typeopts = ({'enums': 'unknown,benign,malicious'})
$propinfo = ({'doc': 'Classification for this FQDN.'})

$lib.model.ext.addFormProp(inet:fqdn, _classification, (str, $typeopts), $propinfo)

Extended Universal Properties

Similar to $lib.model.ext.addFormProp, $lib.model.ext.addUnivProp takes the same propname, typedef, and propinfo arguments, but applies to all forms.

Manage Model Deprecations

As the Synapse Data Model grows and evolves, model elements (types, forms, and properties) may be deprecated and should no longer be used for new data modeling. The Storm model.deprecated commands can be used to prepare for the eventual removal of deprecated model elements.

Lock Deprecated Model Elements

The model.deprecated.lock command edits the lock status of deprecated model elements. Locked model elements can still be viewed or deleted, but can no longer be added. Attempting to add a locked model element will cause an IsDeprLocked error. The model.deprecated.locks command can be used to show the current lock status of all deprecated model elements.

Examples:

Lock the ps:person:img property:

storm> model.deprecated.lock ps:person:img
Locking: ps:person:img

Unlock the ps:person:img property:

storm> model.deprecated.lock --unlock ps:person:img
Unlocking: ps:person:img

Lock all deprecated model elements:

storm> model.deprecated.lock *
Locking all deprecated model elements.

Check for Deprecated Model Elements

The model.deprecated.check command checks for lock status and the existence of deprecated model elements in the Cortex. Warnings will be produced for any deprecated model elements which are unlocked or still in use in the Cortex. Once all warnings have been resolved, your Cortex will be ready for future model updates.

Configure a Mirrored Layer

Note

Mirrored layers are deprecated in 2.x and will be removed in 3.0.0. The layer.pull.add and layer.push.add commands can be used to configure streaming edits to/from layers in a separate Cortex.

Once a mirrored layer is configured, it will need to stream down the entire history of events from the upstream layer. During this process, the layer will be readable but writes will hang due to needing to await the write-back A Cortex may be configured to mirror a layer from a remote Cortex which will synchronize all edits from the remote layer and use write-back support to facilitate edits originating from the downstream layer. The mirrored layer will be an exact copy of the layer on the remote system including all edit history and will only allow changes which are first sent to the upstream layer.

When configuring a mirrored layer, you may choose to mirror from a remote layer or from the top layer of a remote view. If you choose to mirror from the top layer of a remote view, that view will have the opportunity to fire triggers and enforce model constraints on the changes being provided by the mirrored layer.

To specify a remote layer as the upstream, use a Telepath URL which includes the shared object */layer/<layeriden> such as:

aha://cortex.loop.vertex.link/*/layer/8ea600d1732f2c4ef593120b3226dea3

To specify a remote view, use the shared object */view/<viewiden> such as:

aha://cortex.loop.vertex.link/*/view/8ea600d1732f2c4ef593120b3226dea3

When you specify a --mirror option to the layer.add command or within a layer definition provided to the $lib.layer.add() Storm API the telepath URL will not be checked. This allows configuration of a remote layer or view which is not yet provisioned or is currently offline.

Note

To allow write access, the telepath URL must allow admin access to the remote Cortex due to being able to fabricate edit origins. The telepath URL may use aliased names or TLS client side certs to prevent credential disclosure.

Once a mirrored layer is configured, it will need to stream down the entire history of events from the upstream layer. During this process, the layer will be readable but writes will hang due to needing to await the write-back to be fully caught up to guarantee that edits are immediately observable like a normal layer. During that process, you may track progress by calling the getMirrorStatus() API on the layer object within the Storm runtime.