Policies

Overview

Policies for a service are defined in JSON. The JSON file consists of the section "policies" and the optional sections "fallbackPolicy", "properties", "restrictions", and "extensions".

{
    "policies": [],
    "fallbackPolicy": {},   // optional
    "properties": {},       // optional
    "restrictions": {},     // optional
    "extensions": {}        // optional
}

The order of these properties does not matter. If you don’t need them, you can either omit the optional properties or you assign an empty object {}.

Auto-complete and syntax validation

The JSON format for policies definition as described here is also defined as JSON Schema. With this schema you can verify that the JSON file you write is valid. Furthermore, editors like Visual Studio Code can use that schema to provide examples, descriptions, and auto-completion when editing elements.

In the JSON file add the property "$schema" like this to enable auto-complete:

{
    "$schema": "https://raw.githubusercontent.com/conterra/policies-json/1.5.0/schema/policies.schema.json",
    "policies": []
}

A copy of the JSON Schema is included in the security.manager NEXT distribution and available under [SECMAN_DIR]/resources/policies.schema.json. With this copy you can still use auto-complete and syntax validation even if you are working in an environment that doesn’t have access to https://raw.githubusercontent.com/conterra/policies-json/…​. To use this copy, change the value of $schema as follows (replacing [SECMAN_DIR] by the directory’s actual path):

{
    "$schema": "[SECMAN_DIR]/resources/policies.schema.json",
    "policies": []
}

Policies

The "policies" array defines all policies that apply to a service. A single policy is a combination of layers, roles, and optional restrictions.

To grant access to layers with IDs 0 and 1 for role role_division_42 a policy would look like this:

{
    "policies": [
        {
            "layers": ["0", "1"],
            "roles": ["role_division_42"]
        }
    ]
}

Layers

The "layers" property of a "policies" item is an array of layer IDs of a particular map service. Layer IDs can be listed explicitly, as interval, or as "*" which would grant access to all layers.

The following example defines two policies, one applicable to the layers 0 and 3 through 5, and another policy applicable to all layers present on the given service:

{
    "policies": [
        {
            "layers": ["0", "3-5"],
            "roles": ["enhancedSecurity_any"]
        },
        {
            "layers": ["*"],
            "roles": ["role_division_42"]
        }
    ]
}

Roles

The "roles" property of a policy is an array of role IDs. A role ID refers to a particular portal group or ArcGIS Server role assigned to requesting users. If a user authenticates via ArcGIS Enterprise, the role IDs defined in a policy are matched against the user’s portal group IDs or ArcGIS Server role names.

Example: If a user is assigned to portal group "Division 42" and the according group ID in portal is 41477fa98f444444855e1e0b7b132b45, the following policy would grant access to layer 0 of a service:

{
    "policies": [
        {
            "layers": ["0"],
            "roles": ["41477fa98f444444855e1e0b7b132b45"]
        }
    ]
}

You can use the following role IDs to grant access independent of specific user roles:

  • enhancedSecurity_any

  • enhancedSecurity_authenticated

If a policy is bound to the role enhancedSecurity_any it gets applied to any user, no matter what roles she is assigned to or if she was even authenticated by ArcGIS Enterprise. To make policies work that refer to this role, the map service must be made publicly accessible so that anonymous users can connect to it.

If the role enhancedSecurity_authenticated is used, the policy applies to all users who are authenticated at ArcGIS Enterprise.

In the example below, all users are able to access layer 0, but only users authenticated with ArcGIS Enterprise are able to access both, layers 0 and 1.

{
    "policies": [
        {
            "layers": ["0"],
            "roles": ["enhancedSecurity_any"]
        },
        {
            "layers": ["1"],
            "roles": ["enhancedSecurity_authenticated"]
        }
    ]
}

If none of the specified policies match, security.manager NEXT will deny access to the requested resources by default. This behavior can be customized by specifying a fallback policy.

Restrictions

Restrictions limit access to layers. The "restrictions" array of a policy contains a list of IDs that refer to elements in the top-level "restrictions" object of the JSON file.

In the following example the policy refers to the restriction "california" that is defined further down in the file.

{
    "policies": [
        {
            "layers": ["0"],
            "roles": ["${guests}"],
            "restrictions": ["california"]
        }
    ],
    "restrictions": {
        "california": {
            "type": "spatial",
            "featuretypeurl": "https://gis.example.com:6443/arcgis/rest/services/USA/FeatureServer/0",
            "featurequery": "state = 'California'"
        }
    }
}

See the section Restrictions below, for more details on available restriction types.

Fallback policy

The "fallbackPolicy" object customizes the default behavior of security.manager NEXT. If no other policy matches a user’s roles, security.manager NEXT will apply the fallback policy instead.

The fallback policy may use the "layers" and "restrictions" policy properties. It must not use the "roles" property.

In the following example, a single role has complete access to layer 1. All other roles are granted read-only access to the same layer:

{
    "fallbackPolicy": {
        "layers": [
            "1"
        ],
        "restrictions": [
            "readonly"
        ]
    },
    "policies": [
        {
            "roles": [
                "41477fa98f444444855e1e0b7b132b45"
            ],
            "layers": [
                "1"
            ],
            "restrictions": []
        }
    ],
    "restrictions": {
        "readonly": {
            "type": "readonly"
        }
    }
}

It is recommended not to mix "fallbackPolicy" with policies for the "enhancedSecurity_any" role. The policy for "enhancedSecurity_any" would match for all users, which prevents the application of "fallbackPolicy".

Properties

The "properties" array contains key-value-pairs, where the values have to be strings. The keys must start with a letter and only consist of the characters a-z, A-Z, 0-9 as well as '_' (underscore) and '-' (dash). By referencing the key of a property as ${property_name} in other properties it can help to reuse values. Properties can also be used to give values descriptive names.

In the following example the role ID 41477fa98f444444855e1e0b7b132b45 is assigned to the property "guests". It then can be referenced in a policy:

{
    "policies": [
        {
            "layers": ["0"],
            "roles": ["${guests}"]
        }
    ],
    "properties": {
        "guests": "41477fa98f444444855e1e0b7b132b45"
    }
}

Restrictions

A policy may only give limited access to layers by adding restrictions to it.

In the following example the policy refers to the restriction "california" defined in the top-level "restrictions" property.

{
    "policies": [
        {
            "layers": ["0"],
            "roles": ["${guests}"],
            "restrictions": ["california"]
        }
    ],
    "restrictions": {
        "california": {
            "type": "spatial",
            "featuretypeurl": "https://gis.example.com:6443/arcgis/rest/services/USA/FeatureServer/0",
            "featurequery": "state = 'California'"
        }
    }
}

Names used for a restriction (california in the example above) must only consist of the letters a-z, A-Z, 0-9 as well as '_' (underscore) and '-' (dash). They must start with a letter.

You can define the following types of restrictions:

Spatial

Limit access to a certain geographical region.

Field

Limit access to certain fields of a layer.

Feature

Limit access to certain features of a layer.

Editing

Deny editing of geometries and attributes.

Restrictions always apply to all layers referenced in a policy element. When you want to apply different restrictions to different layers, you have to use multiple policy elements.

Spatial restrictions

Spatial restrictions define a geographical region that a user is allowed to get data for. When a spatial restriction is applied to a service request the response will only contain data for the specified region. A spatial restriction defines which part of a map image will be visible. If the user requests feature data like in a query operation, the resulting feature set is limited to the features that intersect the defined region.

You can define the spatial restriction by referencing a geometry provided by an ArcGIS feature service. The reference consists of the following information:

type

Restriction type, must be "spatial".

featuretypeurl

URL referencing a feature service layer, either relative to the current ArcGIS Server or as an absolute URL.

Relative URL

Path to a feature service layer, relative to the root of the current ArcGIS Server. When using relative URLs, even access protected features can be referenced.

Example: "/OptionalFolderName/RestrictionAreas/FeatureServer/0"

Absolute URL

Absolute URL to a feature service layer on an arbitrary ArcGIS Server. Only publicly available features can be used.

Example: "https://gis.example.com:6443/arcgis/rest/services/RestrictionAreas/FeatureServer/0"

featurequery

Definition expression (or WHERE clause) applied to the feature service layer that selects the features making up the restriction area.

You can make use of User Attributes within the query element, like in OWNER = '${user.username}' or DEPARTMENT IN ${user.roles}.

The following example defines a policy granting access to all data of layer 1 that lies inside or intersects the features of https://gis.example.com:6443/arcgis/rest/services/RestrictionAreas/FeatureServer/0 where area_name matches 51.

{
    "policies": [
        {
            "layers": ["1"],
            "roles": ["${guests}"],
            "restrictions": ["area51"]
        }
    ],
    "restrictions": {
        "area51": {
            "type": "spatial",
            "featuretypeurl": "https://gis.example.com:6443/arcgis/rest/services/RestrictionAreas/FeatureServer/0",
            "featurequery": "area_name = '51'"
        }
    }
}

A spatial restriction defined for one layer of a map service will be applied to all layers of this service. For feature services, the spatial restriction can be applied for a layer individually.

Field restrictions

Using field restrictions you can hide certain fields of layers or tables from the user. The actual fields to hide need to be specified as a list of field names.

Create a field restriction by adding a new entry to the top-level "restrictions" property of the JSON file. It must have the following property:

type

Restriction type, must be "field".

Then, specify one of the following mutually exclusive properties:

hiddenfields

An array of field names that should not be accessible for users.

allowedfields

An array of field names that should be accessible for users.

Limitations
  • Technically required fields such as the object id, type id fields, global id field and the display field cannot be hidden.

  • Replicas are not supported when field restrictions are defined.

The following policy defines a restriction for the fields of layer 42. The fields named DIVISION_SIZE and DIVISION_REVENUE will not be accessible for anonymous users.

{
    "policies": [
        {
            "layers": ["42"],
            "roles": ["enhancedSecurity_any"],
            "restrictions": ["secret_division_data"]
        }
    ],
    "restrictions": {
        "secret_division_data": {
            "type": "field",
            "hiddenfields": ["DIVISION_SIZE", "DIVISION_REVENUE"]
        }
    }
}

Feature restrictions

If only a subset features of a layer or table should be accessible for a user, you can use feature restrictions. Feature restrictions are defined as a query expression (definition query) that defines the features that a person can access.

Create a feature restriction by adding a new entry to the top-level "restrictions" property of the JSON file. It must have the following properties:

type

Restriction type, must be "feature".

query

A query expression in the SQL syntax supported by ArcGIS Server, like in the layer restrictions in ArcMap or ArcGIS Pro.

You can reference attributes of the requesting user within the query element.

The following policy defines a restriction for the features of layer 42. Any authenticated user is granted to access features only, where the value of the field DIVISION_NAME equals North.

{
    "policies": [
        {
            "layers": ["42"],
            "roles": ["enhancedSecurity_authenticated"],
            "restrictions": ["northern_division"]
        }
    ],
    "restrictions": {
        "northern_division": {
            "type": "feature",
            "query": "DIVISION_NAME = 'North'"
        }
    }
}

User attributes

Following user attributes are available in definition queries (if set):

Attribute Description Example

${user.username}

The username of the requesting user as known to portal or ArcGIS Server.

OWNER = '${user.username}'
Queries all features where the field OWNER equals the requesting user’s name

${user.roles}

  • Unfederated ArcGIS Server: List of names of all roles assigned to the requesting user.

  • Federated ArcGIS Server: List of IDs of all portal groups the requesting user belongs to.

DEPARTMENTS IN ${user.roles}
Queries all features where the field DEPARTMENT equals one of the user’s roles or group IDs.

The limitation to just these two user attributes is imposed by ArcGIS Enterprise. To allow for feature restrictions based on other information about the requesting user, security.manager NEXT defines an extension API called User Information Service you can implement to deliver more user attributes from arbitrary sources like LDAP or REST services.

Editing restriction

By default, every user with access to a feature service with editing capabilities enabled can manipulate geometries as well as attributive data. This can be denied for specific layers and groups.

type

Restriction type, must be "readonly".

The following policy denies editing of any layer for users of group enhancedSecurity_authenticated.

{
    "policies": [
        {
            "layers": ["*"],
            "roles": ["enhancedSecurity_authenticated"],
            "restrictions": ["editing_denied"]
        }
    ],
    "restrictions": {
        "editing_denied": {
            "type": "readonly"
        }
    }
}

When a user is assigned to more than one group, and for several of these groups access to a certain layer is permitted, then access is granted but enforces the union of all associated restrictions.

This means:

  • Spatial restrictions: Access is granted for the intersection of all geometries referenced by at least one applicable policy.

  • Field restrictions: All fields are hidden that are excluded by at least one applicable policy.

  • Feature restrictions: Access is granted on those features that fulfill all restrictions of the applicable policies.

  • Editing restrictions: Editing is denied when it at least one policy an editing restriction is defined.

Extensions

The "extensions" section allows to activate and configure optional capabilities for policies:

{
    "policies": [],
    ...
    "extensions": {                 //optional
        "<extension_name>" : { }    // extension configuration
    }
}

Visit the Extensions section to get a list of available extensions and their according configuration.