Deliver the right data, at the right time, in the right context.
The feature involves policies, knowledge queries and execution queries.
Creating a CIQ Policy:
An authorization admin defines the rules and mechanisms for dynamically upserting and retrieving data, ensuring that users, systems, and services are granted access in the right context and at the right time. They select specific nodes and relationships, then apply static or partial filters to them. Crucially, one node must always be designated as the Subject node, though different policies can have different Subject nodes. Filters aren't required for every node or relationship. These chosen nodes, relationships, and their filters collectively define the criteria for queries within the policy.
A static filter is a property filter on a node or relationship where the target value is already provided, e.g., group.property.status = 'active' , while partial filters are filters where the target value is provided at evaluation time, e.g., user.property.email = $user_email.
A policy is restricted to a single subject type. If there are 2 subjects (e.g., Person and _Application), 2 policies will need to be created.
Creating a Knowledge Query:
Queries are built using a policy as a guide. Think of the policy as defining what's required (i.e., how the subject and resources should be connected to each other in the graph, and the filters on those nodes and relationships) and what's allowed, while the query tells the system what to do (e.g., retrieve/create/update/delete data). An administrator first picks a policy, then defines how to read, add, or remove data according to the policy. Finally, this combined query and policy are converted into Cypher code.
CIQ Policies and CIQ Knowledge queries are configuration which can be created with Terraform (indykite_authorization_policy and indykite_knowledge_query resources on Terraform) or REST Api (openapi documentation).
They need ServiceAccount credentials, created in the IndyKite Hub or the REST Config API.

Schema example
CIQ Policy Syntax
{
"meta": {
"policy_version": "1.0-ciq"
},
"subject": {
"type": "<string>"
},
"condition": {
"cypher": "<string>",
"filter":
[{
"operator": "<string>",
"attribute" : "<string>",
"value": "<any>",
"operands": [
{
"operator": "<string>",
"attribute": "<string>",
"value": "<any>",
"operands" : [{...}]
}
]
}],
"token_filter" : {
"operator" : "<string>",
"attribute" : "<string>",
"value": "<any>",
"operands" : [
{
"operator": "<string>",
"attribute": "<string>",
"value": "<any>",
"operands" : [{...}],
"advice" : {
"error" : "<string>",
"error_description" : "<string>"
}
}
],
"advice" : {
"error" : "<string>",
"error_description" : "<string>"
}
}
},
"allowed_upserts": {
"nodes": {
"existing_nodes": [
"<string>"
],
"node_types": [
"<string>"
]
},
"relationships": {
"existing_relationships": [
"<string>"
],
"relationship_types": [
{
"type": "<string>",
"source_node_label": "<string>",
"target_node_label": "<string>"
}
]
}
},
"allowed_deletes": {
"nodes": ["<string>"],
"relationships": ["<string>"]
},
"allowed_reads": {
"nodes": [
"<string>"
],
"relationships": [
"<string>"
],
"aggregate_values": [
"<string>"
]
}
}
meta: The metadata for the policy.policy_version: The policy syntax version. The current version is1.0-ciq. (Nothing to do with a version of a policy created by a customer.)
subject: The subject for the policy.type: The node type for the subject.
condition: The condition (requirements) for the policy to be satisfied.cypher: The Cypher query defines the relevant nodes and the relationships that connect them. It may consist ofMATCH,OPTIONAL MATCH,WHERE, andWITHclauses, andWITHclauses may include aggregate functions (for example,COLLECT({username: usernameProp.value}) AS usernames). These clauses specify the graph patterns to match and any filters applied to them, including inline property filters such asMATCH (user:User {id: 1234}), where{id: 1234}acts as an inline constraint. Each node and relationship used in the query must be assigned a variable name if it needs to be referenced later; any element without a variable name cannot be referenced elsewhere in the CIQ query.
filteroperator: The operator for the partial/static filter. The following operators are supported:NOT: Negates the nested filter inoperands.operandsmust contain exactly one entry.
AND: Computes a conjunction of the nested filters inoperands.operandsmust contain one or more entries.
-
OR: Computes a disjunction of the nested filters inoperands.operandsmust contain one or more entries.
-
=: Checks thatattributeEQUALSvalue.
<>: Checks thatattributeis NOT EQUAL tovalue.
>: Checks thatattributeis GREATER THANvalue.
-
<: Checks thatattributeis LESS THANvalue.
-
>=: Checks thatattributeis GREATER THAN OR EQUAL tovalue.
-
<=: Checks thatattributeis LESS THAN OR EQUAL tovalue.
-
IN: Checks theattributeis INvalue(e.g., value in array).
-
=~: Checks theattributematches the string regex provided invalue.
-
STARTS WITH: Checks theattributeis a string value starting withvalue.
-
ENDS WITH: Checks theattributeis a string value ending withvalue.
-
IS NULL: Checks theattributeis not present or NULL.
-
IS NOT NULL: Checks theattributeis present and NOT NULL.
-
attribute: The attribute for comparison for the partial/static filter.attributemust be omitted ifoperatoris either ofAND,OR, orNOT.attributefollows the naming convention:-
$token.<property name>: A property on the requestor token (e.g.,$token.acr).
-
<variable name>.<attribute name>: An attribute on a resource node or a relationship (e.g.,user.external_id).
-
<node variable name>.property.<attribute name>: An attribute on a node (e.g.,user.property.email).
-
<node variable name>.property.<attribute name>.metadata.<metadata attribute name>: A metadata attribute for a property node (e.g.,user.property.email.metadata.source).
-
value: The value for the partial/static filter.valuecan either be hardcoded or set as a variable. Ifvalueis set as a parameter, then it must be a name starting with$(e.g.,"$username").valuemust be omitted ifoperatoris either ofAND,OR, orNOT.
-
operands: Array of nested filters.operandsmust be omitted if it is empty.
-
token_filter: The token filter works similar to the filter above, however this filter only works with$tokenvalues.operator,attribute,value,operands: See above
-
advice: The step up advice from the individual filters that were not satisfied for the token filter. It is based on the optional Advice of Condition structure. The advice is returned in the response body context to the called with theWww-Authenticateheader with advice error "insufficient_user_authentication".error: The name of the error for the individual filter.
error_description: The description for the error.
allowed_upserts: The upserts allowed by the derived queries.allowed_upsertsmust be omitted if it is empty.-
nodes: The nodes to upsert.nodesmust be omitted if it is empty.-
existing_nodes: The list of node variables, that were specified incypherabove, that the derived queries can update. Since the node variable is specified in the cypher, it must already exist in the IKG.existing_nodesmust be omitted if it is empty.
-
node_types: The array of node labels specifying the types of nodes that the derived queries can create in the IKG.node_typesmust be omitted if it is empty.
-
-
relationships: The relationships to upsert.relationshipsmust be omitted if it is empty.-
existing_relationships: The list of relationship variables, that were specified incypherabove, that the derived queries can update. Since the relationship variable is specified in the cypher, it must already exist in the IKG.existing_relationshipsmust be omitted if it is empty.
-
relationship_types: The array or relationship types that the derived queries can create in the IKG.relationship_typesmust be omitted if it is empty.-
type: The type of the relationship.
-
source_node_label: The label for the source node for the relationship.
-
target_node_label: The label for the target node for the relationship.
-
-
-
-
allowed_deletes: The deletes allowed by the derived queries.allowed_deletesmust be omitted if is is empty.-
nodes: The list of nodes (using names like person, person.*), that are mentioned incypherabove, that the derived queries can delete from the IKG. person.* is the wildcard.
-
relationships: The list of relationships (like r1, r1.*), that are mentioned incypherabove, that the derived queries can delete from the IKG. r1* is the wildcard.
-
allowed_reads: The nodes and relationships that derived queries can present as a result.nodes: The list of node variables, specified incypherabove, that the derived query can present as a result.
Example: "allowed_reads": { "nodes": [ "subject", "subject.*", "person", "person.*" ] }
It means that in the CIQ Knowledge Query you will be able to use: either subject, person or subject.something, person.property.something. person.* is the wildcard.
So for example: "nodes": [ "subject", "person" ] }
-
relationships: The list of relationship variables, specified incypherabove, that the derived query can present as a result.
-
aggregate_values: The list of variables introduced through aggregate functions in thecypherabove, that the derived query can present as a result.
CIQ Knowledge Query Syntax
{
"filter":
{
"operator": "<string>",
"attribute": "<string>",
"value": "<any>",
"operands": [
{
"operator": "<string>",
"attribute": "<string>",
"value": "<any>",
"operands" : [{..}]
}
]
},
"upsert_nodes": [
{
"name": "<string>",
"type": "<string>",
"external_id": "<string>",
"properties": [
{
"type": "<string>",
"value": "<any>",
"metadata": [
{
"type": "<string>",
"value": "<any>"
}
]
}
]
}
],
"upsert_relationships": [
{
"name": "<string>",
"source": "<string>",
"target": "<string>",
"type": "<string>",
"properties": [
{
"type": "<string>",
"value": "<any>"
}
]
}
],
"delete_nodes": ["<string>"],
"delete_relationships": ["<string>"],
"nodes": ["<string>"],
"relationships": ["<string>"],
"aggregate_values": ["<string>"]
}
-
filter: Similar to thefilterfor the policy. See above for details.filtermust be omitted if it is empty.
-
upsert_nodes: The array of nodes to upsert.upsert_nodesmust be omitted it is empty.-
name: The variable name for the node to upsert. If updating an existing node in the IKG (i.e., the node that was mentioned in the policycypher), thennameshould match the variable name in the policycypher. If creating a new node in the IKG, thennamemust be distinct from other variables names mentioned in the policy and query.
-
label: The label for the node to upsert.
-
external_id: The external_id for the node.external_idcan be hardcoded in the query or parameterized (variable name staring with$).external_idmust be present if creating a new node in the IKG, otherwise it must be omitted.
-
properties: The array of properties for the node to upsert.propertiesmust be omitted if it is empty.-
type: The name of the type of the property.typemust be hardcoded.
-
value: The value for the property.valuecan either by hardcoded to parameterized (variable name starting with$).
-
-
-
upsert_relationships: The array of relationships to upsert.upsert_relationshipsmust be omitted if it is empty.name: The variable name of the relationship to upsert. If updating an existing relationship in the IKG (i.e., the relationship was mentioned in the policycypher), thennameshould match the variable name in the policycypher. If creating a new relationship in the IKG, thennamemust be distinct from other variables names mentioned in the policy and query.
-
source: The node variable name for the source node of the relationship.sourcemust be empty if updating an existing relationship.
-
target: The node variable node for the target node of the relationship.targetmust be empty if updating an existing relationship.
-
type: The type of the relationship.typemust be empty if updating an existing relationship.
-
properties: The array of properties for the relationship to upsert.propertiesmust be omitted if it is empty.-
type: The name of the type of the property.typemust be hardcoded.
-
value: The value for the property.valuecan either by hardcoded to parameterized (variable name starting with$).
-
metadata: The array of property metadata.metadatamust be omitted if it is empty.-
type: The name of the type of metadata.typemust be hardcoded.
-
value: The value for the metadata.valuecan either be hardcoded or parameterized (variable name starting with$).
-
-
-
delete_nodes: Array of nodes variable names for the nodes the query will delete. The entries indelete_nodesmust match node variables names in the policycypher(like car, car.property.model).
-
delete_relationships: Array of relationship variable names for the relationships the query will delete. The entries indelete_relationshipsmust match relationship variable names in the policycypher(like r1, r1.status).
The following properties cannot be deleted: _service, create_time, external_id, id, type, update_time.
-
nodes: Array of node variables names that the query will return as a result. The entries innodesmust match node variables names mentioned in the policycypherornames inupsert_nodes.
-
relationships: Array of relationship variable names that the query will return as a result. The entries inrelationshipsmust match relationship variable names mentioned in the policycypherornames inupsert_relationships.
-
aggregate_values: Array of variables introduced through an aggregate function in the policycypherthat the query will return as a result.
CIQ Execution Query Syntax
The CIQ Execution Queries are REST API requests, referencing the id or the name of the stored CIQ Knowledge Query.
A request pass the required input parameters, representing the values for each partial filter variable in the CIQ Knowledge query and the CIQ policy, and the CIQ Knowledge gid or name.
The request will convert the CIQ Knowledge query and the CIQ policy into a cypher, execute it and return the result.
The result contains the values for the variables defined in nodes and relationships in the CIQ Knowledge Query.
Endpoint: POST /contx-iq/v1/execute
They need AppAgent credentials created in the IndyKite Hub, using the REST endpoints or using Terraform for your Project / Application.
APIKey authentication with Key: X-IK-ClientKey and value: AppAgent credentials token.
If the subject type in the policy is anything other than "_Application", then the request also needs a third party bearer token.
When the subject is _Application, the $_appId input does not need to be provided in the CIQ Execution Query and is automatically assigned the subject.external_id value (external_id property in the Application node).
Request example:
{
"id": "knowledge_query_gid",
"input_params": {
"subject_external_id": "subject_external_id_value",
"token_sub": "token_sub_value",
"license_number": "license_number_value"
}
}
Response example:
{
"data": [
{
"nodes": {
"company.external_id": "companyParking",
"payment.external_id": "cb123",
"subject.external_id": "subject_external_id_value"
}
},
{
"relationships": {
.....
}
}....
]
}