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:
Storm Libraries that allow you to work with a broad range of objects in Synapse.
Synapse tools that can be used from the host CLI (as opposed to the Storm CLI). Tools are available in the synapse.tools package of the Synapse Python API. The Synapse User Guide includes documentation on some of these Tools.
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: d91d27191b8ace7998f4bd39152d8fb4
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 (d91d27191b8ace7998f4bd39152d8fb4)
Locked: false
Admin: false
Email: [email protected]
Rules:
Roles:
fd7d43522140a1ac81a5287a5994fbbf - 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: f0d01c15df0dae3924724549e6251536
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 (fd7d43522140a1ac81a5287a5994fbbf)
Rules:
Gates:
18c92391771078f3d4359b4d6a90c374 - (layer)
[0 ] - layer.read
0d9f47bd3e1badac6e32e5af581c68d4 - (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) |
|
Add any kind of node (but not delete nodes, or work with properties, tags, edges, or node data) |
|
Only add (but not set properties, or work with tags or edges) |
|
Only add (set) the (but not create nodes or work with other properties, tags, edges, etc.) |
|
Add or remove any tag (Note that adding/removing tags may require the ability to create |
|
Only add and remove tags in the “mytag” tag tree |
|
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.) |
|
Only add edges |
|
Only add |
|
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 withworldreadable=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 withauth.user.addrule
orauth.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: 0d9f47bd3e1badac6e32e5af581c68d4 (name: default)
Creator: c29592232d3c8bac5ce63b8c98b9895d
Layers:
18c92391771078f3d4359b4d6a90c374: default readonly: False
Display the current layer:
storm> layer.get
Layer: 18c92391771078f3d4359b4d6a90c374 (name: default) readonly: False creator: c29592232d3c8bac5ce63b8c98b9895d
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:
c29592232d3c8bac5ce63b8c98b9895d - root
Admin: true
Rules:
Auth Gate Roles:
fd7d43522140a1ac81a5287a5994fbbf - 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:
c29592232d3c8bac5ce63b8c98b9895d - root
Admin: true
Rules:
Auth Gate Roles:
fd7d43522140a1ac81a5287a5994fbbf - 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-inall
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 bynode
). 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 |
---|---|
|
See / read any view |
|
Fork any view they can see |
|
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 globalview.read
access. To allow theall
role (or any role) to see other views, you must explicitly assign theview.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, theview.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 |
---|---|---|
|
global |
Fork any view they can see (based on |
|
global |
Prevent deletion of any nodes |
|
global |
Create nodes in the top layer of any view they can see |
|
global |
Set, modify, or delete node properties in the top layer of any view they can see |
|
global |
Add or remove light edges in the top layer of any view they can see |
|
global |
Add or remove tags from nodes in the top layer of any view they can see |
|
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
oragents of destruction
, but you can just usedeleters
.
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 |
---|---|
|
Add / apply tags in the
|
|
Remove any tags in the |
|
Add / apply any tags in the |
|
Remove any tags in the |
|
Add |
|
Delete |
|
Add |
|
Delete |
|
Add |
|
Delete |
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 forrisk: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 |
---|---|
|
Prevent creating these nodes |
|
Prevent setting this property (i.e., on existing
|
|
Prevent applying tags in the |
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 |
|
Prevent applying tags in the
assessements) but apply other tags |
novice analyst |
|
Novices can apply tags in the (representing third-party reporting) |
junior analyst |
|
Junior analysts can apply tags in the
infrastructure) |
senior analyst |
|
Senior analysts can apply tags in the
(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 |
---|---|
|
Apply families - e.g., |
|
Apply family ecosystems, such as related droppers or C2 - e.g.,
|
|
Apply as part of a malware ecosystem but are not inherently malicious - e.g., |
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
ornode.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 |
---|---|
|
Create organization nodes |
|
Assign organizations to one or more industries |
|
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.archived
Controls archiving/unarchiving a user account.
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.kill
Controls the ability to terminate a running cron job.
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 and values.
gate: cortex
default: false
model.prop.del.<form>
Controls access to deleting specific extended model properties and values.
gate: cortex
default: false
example: model.prop.del._foo:bar
model.tagprop.add
Controls access to adding extended model tag properties and values.
gate: cortex
default: false
model.tagprop.del
Controls access to deleting extended model tag properties and values.
gate: cortex
default: false
model.type.add
Controls access to adding extended model types.
gate: cortex
default: false
model.type.add.<type>
Controls access to adding specific extended model types.
gate: cortex
default: false
example: model.type.add._foo:bar
model.type.del
Controls access to deleting extended model types.
gate: cortex
default: false
model.type.del.<type>
Controls access to deleting specific extended model types.
gate: cortex
default: false
example: model.type.del._foo:bar
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 and values.
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.data.pop
Permits a user to remove node data in a given layer.
gate: layer
default: false
node.data.pop.<key>
Permits a user to remove node data in a given layer for a specific key.
gate: layer
default: false
example: node.data.pop.hehe
node.data.set
Permits a user to set node data in a given layer.
gate: layer
default: false
node.data.set.<key>
Permits a user to set node data in a given layer for a specific key.
gate: layer
default: false
example: node.data.set.hehe
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.stix.export.maxsize
Controls the ability to specify a STIX export bundle maxsize of greater than 10,000.
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
task.del
Controls access to terminate other users tasks.
gate: cortex
default: false
task.get
Controls access to view other users tasks.
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).
See the Optic Deployment Guide for information on Optic deployment.
See the Optic DevOps Guide for information on Optic permissions and other features.
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:
Synapse-PSL (FQDN public suffix list)
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 propertypropinfo
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.