Policies
CipherTrust Manager authorizes operations using an Attribute-Based Access Control (ABAC) model. In ABAC, access control policies are defined by the attributes of the components involved in a request. These components typically include the user, the target resource (such as a cryptographic key), and the request's environment (which encompasses attributes like time of day, source IP address, geographic region, and incoming port).
Warning
Modifying policies, including the default ones, is an advanced operation. Incorrect changes can lead to system lockouts and render CipherTrust Manager unusable. It is strongly recommended that policy modifications are only performed in consultation with Thales Technical Support.
CipherTrust Manager ABAC system is inspired by XACML and Amazon AWS policies.
An ABAC policy can use the attributes of any of these components to decide if the policy applies to a given request. For example, an ABAC policy could state: "Allow reading Key XYZ, but only at night, if the Key is 'enabled', the user belongs to the 'hr' department and is an admin, and the request originates from the internal port."
ABAC is advantageous as it encompasses other commonly used access control systems, such as Role-Based Access Control (RBAC). RBAC can be implemented using ABAC policies defined in terms of a user's "role" attribute.
CipherTrust Manager ABAC policies are expressed in terms of two resources: Policies and Policy Attachments.
Policy composition
A Policy is composed of:
a set of actions (i.e. operations)
a set of targets
a rule, either "allow" or "deny"
a set of conditions (optional)
Conditions are matching rules tested against the request to further refine the set of requests to which a Policy applies. For example, a simple policy might be:
allow read and write to key ABC and key XYZ
.Conditions can further refine this policy. For example, the policy
allow read and write to key ABC and key XYZ
could be made more specific with the following cumulative conditions:The key is intended for document signing.
The user belongs to the "Signers" group.
The request originates from an internal IP address.
Policy attachments
Policies are not enforced on their own; they must be attached to a set of users. This is achieved by creating Policy Attachments.
A Policy Attachment links a single policy to a set of users. This set of users is defined by a matching rule (similar to policy conditions) that is tested against the user information in the API token. For example, policy attachments can match a single user, all users in a specific group, users who have a particular flag in their metadata, or all users. If the principalSelector
field in the policy attachment JSON is an empty object ({}
), the policy applies to all users.
For example, if the policy described earlier is named "Internal HR Key Usage," it could be enforced by attaching it to users in the HR department. The Policy Attachment would specify:
Policy: Internal HR Key Usage
Attached To: Users in the HR department
This might seem confusing because a policy's conditions can also refer to user attributes. For instance, the "Signers" group condition could be moved from the policy to the policy attachment with the same outcome. This overlap is intentional, providing flexibility in how policies are expressed and applied.
Default policies
On launch, CipherTrust Manager is pre-installed with a set of Policies and Policy Attachments, which define a default set of group based access controls. However, admins can add to, revise, or replace these Policies with their own, to implement almost any kind of access control regime.
Warning
As emphasized previously, modifying policies, including the default ones, is an advanced operation. Incorrect changes can lead to system lockouts and render CipherTrust Manager unusable. It is strongly recommended that policy modifications are only performed in consultation with Thales Technical Support.
The default policies enforce the following access control rules:
The
admin
user has unrestricted access.Members of the
admin
group have unrestricted access.All users can create keys
Users can perform any operation on keys they created (that is, they "own" the keys).
Key owners can grant group permissions to their keys.
Users in the
global
group can perform most operations on keys that have theglobal
flag set.
Taken together, these policies implement an authorization model that mimics SafeNet KeySecure Classic:
All Users can create keys, which they "own"
Users have admin privileges to the keys they own
Key owners can grant user groups limited usage privileges to their keys
Usage
Policies are powerful primitives. Misconfiguration can lead to locking out all access to CipherTrust Manager. Future enhancements may include pre-defined policy sets for common access control models (like RBAC) and safeguards against irreversible admin lockouts.
Managing login authentication for local users using policies
CipherTrust Manager allows you to create policies to manage local user authentication based on interfaces and client applications. Policies are not enforced automatically; they must be assigned to users or groups via policy attachment.
Interfaces
To create a policy based on interface attributes, use one of the following options for conditions:
Interface name - specify the
path
ascontext.environment.interface.name
and specify the required values in thevalues
parameter, for example, "values": ["nae_all_123"].Interface port - specify the
path
ascontext.environment.interface.port
and specify the required values in thevalues
parameter, for example, "values": [1234].Interface type - specify the
path
ascontext.environment.interface.type
and specify the required values in thevalues
parameter, for example, "values": ["nae"]The CipherTrust Manager supports the following values for Interface type:
nae
for NAE interfacekmip
for KMIP interfaceweb
for any interface other than NAE and KMIP (for example, UI, API playground, ksctl, direct API requests).
Example - Block users in a group from logging in to Web interface using policies
The web
interface type covers login requests from the UI, API playground, ksctl, and direct API requests from external clients. To block a group of users from logging in via the web
interface, follow these steps:
Create a policy
First, create a policy. In this example, the policy is named Blocked Web Users
.
{
"name": "Blocked Web Users",
"effect": "deny",
"resources": [],
"actions": [
"IssueJWT"
],
"conditions": [
{
"op": "equals",
"path": "context.environment.interface.type",
"values": [
"web"
]
}
]
}
Create a policy attachment
Then, create a policy attachment to apply this policy to users in the "Blocked Web Users" group.
{
"policy": "id-of-the-policy-from-previous-api",
"principalSelector": {
"cust": {
"groups": ["Blocked Web Users"]
}
}
}
Client IP
Caution
Exercise extreme caution when configuring IP address allowlists. An incorrect allowlist configuration can lock out all users, including administrators, rendering the entire cluster inaccessible and unmodifiable.
The Admin Disaster Recovery feature cannot resolve this type of lockout. If this occurs, contact Thales Customer Support for assistance.
When creating allowlisting policies, ensure you account for all client IPs that communicate with any node in the CipherTrust Manager cluster. Policies apply cluster-wide, not just to a specific node.
Note
Policies created to manage authentication based on the Client IP parameter don't apply to the requests coming to the NAE and KMIP interfaces with "anonymous login" mode enabled.
Client IP-based authentication policies do not apply to requests on NAE and KMIP interfaces if "anonymous login" mode is enabled for those interfaces.
CipherTrust Manager allows you to create policies that permit or deny local user authentication based on client IP addresses. Only users whose requests match these IP-based policies (and other authentication criteria) can obtain a JWT to access CipherTrust Manager.
When defining conditions for client IP policies, use the following parameters:
effect
: Set the value to "deny".path
: Usecontext.environment.client_ip
for IP-based conditions. For policies specific to certain ports, you'll typically combine an IP condition with an interface port condition (for example,context.environment.interface.port
in a separate condition object).values
: Specify the IPs to be allowed or blocked.negate
: Set value totrue
to allow the IPs. Default value isfalse
.Note
To control access based on client IPs for JWT issuance:
To allowlist specific IPs (Permit only listed IPs): Set
"effect": "deny"
and"negate": true
in the policy condition. This configuration denies access to all IPs not explicitly listed in thevalues
array.To denylist specific IPs (Block listed IPs): Set
"effect": "deny"
and"negate": false
(or omitnegate
, asfalse
is the default). This configuration denies access to all IPs explicitly listed in thevalues
array.
In both scenarios, the
actions
array in the policy should include"IssueJWT"
.
Create a policy to allow client IPs
To create a policy to allow client IPs:
Syntax
ksctl policy create --jsonfile <json-file>
Example Request
ksctl policy create --jsonfile allow-specific-ips-policy.json
allow-specific-ips-policy.json
{
"name": "Allow Certain ip",
"effect": "deny",
"resources": [],
"actions": [ "IssueJWT"],
"conditions": [ {
"negate":true,
"op": "equals",
"path": "context.environment.client_ip",
"values": [
"192.168.1.5","192.168.5.2"
]
}]
}
Example Response
{
"id": "07d10481-7d88-4a48-ad2a-8dc2efd6b40f",
"uri": "kylo:kylo:admin:policies:allow-certain-ip-07d10481-7d88-4a48-ad2a-8dc2efd6b40f",
"account": "kylo:kylo:admin:accounts:kylo",
"application": "ncryptify:gemalto:admin:apps:kylo",
"devAccount": "ncryptify:gemalto:admin:accounts:gemalto",
"createdAt": "2023-07-26T07:58:45.006746Z",
"name": "Allow Certain ip",
"deletedAt": null,
"updatedAt": "2023-07-26T07:58:45.006746Z",
"actions": [
"IssueJWT"
],
"resources": [],
"allow": false,
"effect": "deny",
"conditions": [
{
"path": "context.environment.client_ip",
"op": "equals",
"values": [
"192.168.1.5",
"192.168.5.2"
],
"negate": true
}
]
}
Attaching the Policy
To enforce the policy, attach it to the desired principals. Use the id
returned when the policy was created. An empty principalSelector
({}
) in the attachment JSON applies the policy to all users.
Syntax
ksctl polattach create --polid <policy-id> --prinjson <principal-selector-json-file>
Example Request
ksctl polattach create --polid 07d10481-7d88-4a48-ad2a-8dc2efd6b40f --prinjson attachment.json
attachment.json
{}
Example Response
{
"id": "4deb1d53-31d7-452a-8b55-0400d502e8ee",
"uri": "kylo:kylo:admin:policy-attachments:4deb1d53-31d7-452a-8b55-0400d502e8ee",
"account": "kylo:kylo:admin:accounts:kylo",
"application": "ncryptify:gemalto:admin:apps:kylo",
"devAccount": "ncryptify:gemalto:admin:accounts:gemalto",
"createdAt": "2023-07-26T07:59:02.935252Z",
"updatedAt": "2023-07-26T07:59:02.935252Z",
"policy": "kylo:kylo:admin:policies:allow-certain-ip-07d10481-7d88-4a48-ad2a-8dc2efd6b40f",
"jurisdiction": "kylo:kylo:admin:accounts:kylo",
"principalSelector": {},
"includeExternalPrincipals": false,
"name": "Allow Certain ip",
"actions": [
"IssueJWT"
],
"resources": [],
"allow": false,
"effect": "deny",
"conditions": [
{
"path": "context.environment.client_ip",
"op": "equals",
"values": [
"192.168.1.5",
"192.168.5.2"
],
"negate": true
}
]
}
Create a policy to block client IPs
To create a policy to block client IPs:
Syntax
ksctl policy create --jsonfile <json-file>
Example Request
ksctl policy create --jsonfile block-example.json
block-example.json
{
"name": "Block ips",
"effect": "deny",
"resources": [],
"actions": [
"IssueJWT"
],
"conditions": [
{
"op": "equals",
"path": "context.environment.client_ip",
"values": [
"192.168.1.5",
"192.168.5.2"
]
}
]
}
Example Response
{
"id": "bbc6e24a-fdae-44c6-bd1d-dacb1a3ef874",
"uri": "kylo:kylo:admin:policies:block-aman-bbc6e24a-fdae-44c6-bd1d-dacb1a3ef874",
"account": "kylo:kylo:admin:accounts:kylo",
"application": "ncryptify:gemalto:admin:apps:kylo",
"devAccount": "ncryptify:gemalto:admin:accounts:gemalto",
"createdAt": "2023-07-25T09:46:01.863493Z",
"name": "Block ips",
"deletedAt": null,
"updatedAt": "2023-07-25T09:46:01.863493Z",
"actions": [
"IssueJWT"
],
"resources": [],
"allow": false,
"effect": "deny",
"conditions": [
{
"path": "context.environment.client_ip",
"op": "equals",
"values": [
"192.168.1.5",
"192.168.5.2"
]
}
]
}
Attaching the Policy
To enforce the policy, attach it. Use the id
from the policy creation response.
Syntax
ksctl polattach create --polid <policy-id> --prinjson <principal-selector-json-file>
Example Request
ksctl polattach create --polid bbc6e24a-fdae-44c6-bd1d-dacb1a3ef874 --prinjson block-attachment.json
block-attachment.json
{}
Example Response
{
"id": "5e188e61-78c9-4711-851f-025363214cbc",
"uri": "kylo:kylo:admin:policy-attachments:5e188e61-78c9-4711-851f-025363214cbc",
"account": "kylo:kylo:admin:accounts:kylo",
"application": "ncryptify:gemalto:admin:apps:kylo",
"devAccount": "ncryptify:gemalto:admin:accounts:gemalto",
"createdAt": "2023-07-25T09:47:22.751751Z",
"updatedAt": "2023-07-25T09:47:22.751751Z",
"policy": "kylo:kylo:admin:policies:block-aman-bbc6e24a-fdae-44c6-bd1d-dacb1a3ef874",
"jurisdiction": "kylo:kylo:admin:accounts:kylo",
"principalSelector": {},
"includeExternalPrincipals": false,
"name": "Block ip",
"actions": [
"IssueJWT"
],
"resources": [],
"allow": false,
"effect": "deny",
"conditions": [
{
"path": "context.environment.client_ip",
"op": "equals",
"values": [
"192.168.1.5",
"192.168.5.2"
]
}
]
}
Create a policy to allow client IPs of a subnet
To create a policy to allow client IPs of a specific subnet:
Syntax
ksctl policy create --jsonfile <json-file>
Example Request
ksctl policy create --jsonfile allow-subnet-policy.json
allow-subnet-policy.json
{
"name": "Allow IPs of a Subnet",
"effect": "deny",
"resources": [],
"actions": [ "IssueJWT"],
"conditions": [ {
"negate": true,
"op": "regex",
"path": "context.environment.client_ip",
"values": [
"165.225.*"
]
}]
}
Example Response
{
"id": "367969df-e591-4497-a7e6-55ecfa3e9c08",
"uri": "kylo:kylo:admin:policies:allow-certain-ip-367969df-e591-4497-a7e6-55ecfa3e9c08",
"account": "kylo:kylo:admin:accounts:kylo",
"application": "ncryptify:gemalto:admin:apps:kylo",
"devAccount": "ncryptify:gemalto:admin:accounts:gemalto",
"createdAt": "2023-11-17T09:11:56.05426Z",
"name": "Allow IPs of a Subnet",
"deletedAt": null,
"updatedAt": "2023-11-17T09:11:56.05426Z",
"actions": [
"IssueJWT"
],
"resources": [],
"allow": false,
"effect": "deny",
"conditions": [
{
"path": "context.environment.client_ip",
"op": "regex",
"values": [
"165.225.*"
],
"negate": true
}
]
}
In the above example, all the IPs of the subnet 165.225.0.0/16
will be allowed.
Attaching the Policy
To enforce the policy, attach it. Use the id
from the policy creation response.
Syntax
ksctl polattach create --polid <policy-id> --prinjson <principal-selector-json-file>
Example Request
ksctl polattach create --polid 367969df-e591-4497-a7e6-55ecfa3e9c08 --prinjson attachment.json
attachment.json
{}
Create a policy to block client IPs of a subnet
To create a policy to block client IPs of a specific subnet:
Syntax
ksctl policy create --jsonfile <json-file>
Example Request
ksctl policy create --jsonfile block-subnet-policy.json
block-subnet-policy.json
{
"name": "Block IPs of a Subnet",
"effect": "deny",
"resources": [],
"actions": [ "IssueJWT"],
"conditions": [ {
"op": "regex",
"path": "context.environment.client_ip",
"values": [
"165.225.*"
]
}]
}
Example Response
{
"id": "21c8cfe4-cba2-436a-85fc-2df7b22afbd7",
"uri": "kylo:kylo:admin:policies:block-certain-ip-21c8cfe4-cba2-436a-85fc-2df7b22afbd7",
"account": "kylo:kylo:admin:accounts:kylo",
"application": "ncryptify:gemalto:admin:apps:kylo",
"devAccount": "ncryptify:gemalto:admin:accounts:gemalto",
"createdAt": "2023-11-17T09:12:24.23122Z",
"name": "Block IPs of a Subnet",
"deletedAt": null,
"updatedAt": "2023-11-17T09:12:24.23122Z",
"actions": [
"IssueJWT"
],
"resources": [],
"allow": false,
"effect": "deny",
"conditions": [
{
"path": "context.environment.client_ip",
"op": "regex",
"values": [
"165.225.*"
]
}
]
}
In the above example, all the IPs of the subnet 165.225.0.0/16
will be blocked.
Attaching the Policy
To enforce the policy, attach it. Use the id
from the policy creation response.
Syntax
ksctl polattach create --polid <policy-id> --prinjson <principal-selector-json-file>
Example Request
ksctl polattach create --polid 21c8cfe4-cba2-436a-85fc-2df7b22afbd7 --prinjson block-attachment.json
block-attachment.json
{}
Create a policy to allow specific client IPs for ports
To create a policy to allow specific client IPs for ports:
Syntax
ksctl policy create --jsonfile <json-file>
Example Request
ksctl policy create --jsonfile allow-ip-for-ports-policy.json
allow-ip-for-ports-policy.json
{
"name": "Allow ip for a specific port",
"effect": "deny",
"resources": [],
"actions": [ "IssueJWT"],
"conditions": [ {
"op": "equals",
"path": "context.environment.interface.port",
"values": [
"9001","9902","9903"
]
},
{
"negate" : true,
"op": "equals",
"path": "context.environment.client_ip",
"values": [
"122.185.33.186"
]
}]
}
Example Response
{
"id": "282b2e01-02f7-429a-aaa6-a7e9af939dee",
"uri": "kylo:kylo:admin:policies:allow-certain-ip2-282b2e01-02f7-429a-aaa6-a7e9af939dee",
"account": "kylo:kylo:admin:accounts:kylo",
"application": "ncryptify:gemalto:admin:apps:kylo",
"devAccount": "ncryptify:gemalto:admin:accounts:gemalto",
"createdAt": "2023-11-17T09:08:46.127197Z",
"name": "Allow ip for a specific port",
"deletedAt": null,
"updatedAt": "2023-11-17T09:08:46.127197Z",
"actions": [
"IssueJWT"
],
"resources": [],
"allow": false,
"effect": "deny",
"conditions": [ {
"op": "equals",
"path": "context.environment.interface.port",
"values": [
"9001","9902","9903"
]
},
{
"path": "context.environment.client_ip",
"op": "equals",
"values": [
"122.185.33.186"
],
"negate": true
}
]
}
In the above example, only 122.185.33.186
IP will be allowed for ports "9001, 9902, and 9903".
Attaching the Policy
To enforce the policy, attach it. Use the id
from the policy creation response.
Syntax
ksctl polattach create --polid <policy-id> --prinjson <principal-selector-json-file>
Example Request
ksctl polattach create --polid 282b2e01-02f7-429a-aaa6-a7e9af939dee --prinjson attachment.json
attachment.json
{}
Create a policy to block specific client IPs for ports
To create a policy to block specific client IPs for ports:
Syntax
ksctl policy create --jsonfile <json-file>
Example Request
ksctl policy create --jsonfile block-ip-for-ports-policy.json
block-ip-for-ports-policy.json
{
"name": "Block ips for a specific port",
"effect": "deny",
"resources": [],
"actions": [ "IssueJWT"],
"conditions": [ {
"op": "equals",
"path": "context.environment.interface.port",
"values": [
"9001","9902","9903"
]
},
{
"op": "equals",
"path": "context.environment.client_ip",
"values": [
"122.185.33.186"
]
}]
}
Example Response
{
"id": "ae705635-056a-47a4-801c-0bdf8681b74a",
"uri": "kylo:kylo:admin:policies:block-certain-ip2-ae705635-056a-47a4-801c-0bdf8681b74a",
"account": "kylo:kylo:admin:accounts:kylo",
"application": "ncryptify:gemalto:admin:apps:kylo",
"devAccount": "ncryptify:gemalto:admin:accounts:gemalto",
"createdAt": "2023-11-17T07:43:35.614821Z",
"name": "Block ips for a specific port",
"deletedAt": null,
"updatedAt": "2023-11-17T07:43:35.614821Z",
"actions": [
"IssueJWT"
],
"resources": [],
"allow": false,
"effect": "deny",
"conditions": [ {
"op": "equals",
"path": "context.environment.interface.port",
"values": [
"9001","9902","9903"
]
},
{
"path": "context.environment.client_ip",
"op": "equals",
"values": [
"122.185.33.186"
]
}
]
}
In the above example, only 122.185.33.186
IP will be blocked for "9001, 9902, and 9903" ports.
Attaching the Policy
To enforce the policy, attach it. Use the id
from the policy creation response.
Syntax
ksctl polattach create --polid <policy-id> --prinjson <principal-selector-json-file>
Example Request
ksctl polattach create --polid ae705635-056a-47a4-801c-0bdf8681b74a --prinjson attachment.json
attachment.json
{}
Client applications
For policies based on client applications, use the path
as context.environment.principal.client_app
. Specify the application types in the values
parameter (for example, "values": ["nae"]
).
nae
kmip
Example - Login to nae and kmip interfaces using policies
To allow login to nae and kmip interfaces irrespective of the authentication methods set for the user, perform the following steps:
Create a policy
{
"name": "Allow Login to NAE/KMIP",
"effect": "allow",
"resources": [],
"actions": [
"IssueJWT"
],
"conditions": [
{
"op": "equals",
"path": "context.environment.principal.client_app",
"values": [
"nae",
"kmip"
]
}
]
}
Create a policy attachment
{
"policy": "id-of-the-policy-from-previous-api",
"principalSelector": {}
}