ContX IQ: With _Application node as a subject, read resources and upsert relationships and nodes.
The _Application node as a subject is allowed to see all resources. Then a relationship between the subject a resource node is created.
Use case
When a new Application with new credentials is created, _Application and _AppAgent nodes are created in the IKG.
In order to create a relationship between these nodes and the ingest data, a CIQ write query can be used.
This will allow the use of the _Application as an authenticated subject.
In this case, a READ is executed on Car nodes then a relationship is created between the subject _Application and a Car node.
A READ is then executed to see the result.
Finally, a new Car is created.

Requirements
- ServiceAccount credentials created in the IndyKite Hub for your organization.
- AppAgent credentials created in the IndyKite Hub, using the REST endpoints or using Terraform for your Project / Application.
Steps
1. Using the AppAgent credential as API Key (name: X-IK-ClientKey), ingest data in your IKG (IndyKite Knowledge Graph) using the script provided.
2. Using the ServiceAccount credential as Bearer token, create a CIQ Policy which designates the nodes which are allowed to be read and the nodes which are allowed to be upserted.
3. Using the ServiceAccount credential as Bearer token, create a CIQ Query to read the Car nodes.
4. Using the AppAgent credential as API Key (name: X-IK-ClientKey), run a CIQ Execution to read a Car node.
5. Using the ServiceAccount credential as Bearer token, create a CIQ Query to upsert relationships USES between the subject and Car nodes.
6. Using the AppAgent credential as API Key (name: X-IK-ClientKey), run a CIQ Execution to upsert one relationship USES between the subject and a Car node.
7. Using the ServiceAccount credential as Bearer token, create a CIQ Policy which designates the nodes which are allowed to be read and the nodes which are allowed to be upserted, according to the graph created previously.
8. Using the ServiceAccount credential as Bearer token, create a CIQ Query to read the Car nodes.
9. Using the AppAgent credential as API Key (name: X-IK-ClientKey), run a CIQ Execution to read a Car node.
10. Using the ServiceAccount credential as Bearer token, create a CIQ Policy which designates only the subject _Application and then the Car nodes which are allowed to be upserted.
11. Using the ServiceAccount credential as Bearer token, create a CIQ Query to upsert new Car nodes.
12. Using the AppAgent credential as API Key (name: X-IK-ClientKey), run a CIQ Execution to upsert a Car node.
Step 1
Ingest the nodes needed for this use case.
{
"nodes": [
{
"external_id": "alice",
"is_identity": true,
"type": "Person",
"properties": [
{
"type": "email",
"value": "alice@email.com"
},
{
"type": "given_name",
"value": "Alice"
},
{
"type": "last_name",
"value": "Smith"
}
]
},
{
"external_id": "knightrider",
"type": "Person",
"is_identity": true,
"properties": [
{
"type": "email",
"value": "knightrider@demo.com"
},
{
"type": "name",
"value": "Michael Knight"
}
]
},
{
"external_id": "satchmo",
"type": "Person",
"is_identity": true,
"properties": [
{
"type": "email",
"value": "satchmo@demo.com"
},
{
"type": "name",
"value": "Louis Armstrong"
}
]
},
{
"external_id": "karel",
"type": "Person",
"is_identity": true,
"properties": [
{
"type": "email",
"value": "karel@demo.com"
},
{
"type": "name",
"value": "Karel Plihal"
}
]
},
{
"external_id": "kitt",
"type": "Car",
"is_identity": false,
"properties": [
{
"type": "manufacturer",
"value": "pontiac"
},
{
"type": "model",
"value": "Firebird"
}
]
},
{
"external_id": "cadillacv16",
"type": "Car",
"is_identity": false,
"properties": [
{
"type": "manufacturer",
"value": "Cadillac"
},
{
"type": "model",
"value": "V-16"
}
]
},
{
"external_id": "harmonika",
"type": "Bus",
"is_identity": false,
"properties": [
{
"type": "manufacturer",
"value": "Ikarus"
},
{
"type": "model",
"value": "280"
}
]
},
{
"external_id": "listek",
"type": "Ticket",
"is_identity": false
},
{
"external_id": "airbook-xyz",
"type": "Laptop",
"is_identity": false
}
]
}Ingest the relationships needed for this use case.
{
"relationships": [
{
"source": {
"external_id": "knightrider",
"type": "Person"
},
"target": {
"external_id": "kitt",
"type": "Car"
},
"type": "DRIVES"
},
{
"source": {
"external_id": "satchmo",
"type": "Person"
},
"target": {
"external_id": "cadillacv16",
"type": "Car"
},
"type": "DRIVES"
},
{
"source": {
"external_id": "karel",
"type": "Person"
},
"target": {
"external_id": "listek",
"type": "Ticket"
},
"type": "HAS"
},
{
"source": {
"external_id": "listek",
"type": "Ticket"
},
"target": {
"external_id": "harmonika",
"type": "Bus"
},
"type": "FOR"
},
{
"source": {
"external_id": "karel",
"type": "Person"
},
"target": {
"external_id": "airbook-xyz",
"type": "Laptop"
},
"type": "OWNS"
},
{
"source": {
"external_id": "alice",
"type": "Person"
},
"target": {
"external_id": "airbook-xyz",
"type": "Laptop"
},
"type": "OWNS"
},
{
"source": {
"external_id": "knightrider",
"type": "Person"
},
"target": {
"external_id": "kitt",
"type": "Car"
},
"type": "OWNS"
},
{
"source": {
"external_id": "alice",
"type": "Person"
},
"target": {
"external_id": "cadillacv16",
"type": "Car"
},
"type": "DRIVES"
}
]
}Step 2
Create a CIQ Policy which designates the nodes which are allowed to be read and the nodes which are allowed to be upserted.
The policy filters first on subject.external_id.
When the subject is _Application, the $_appId input does not need to be provided and is automatically assigned the subject.external_id value.
The policy also filters on car.external_id. The $carId input will need to be provided in the CIQ Execution.
The policy allows the Car nodes to be read, existing Car nodes to be upserted and new relationships between the subject and Car nodes to be upserted
{
"meta": {
"policy_version": "1.0-ciq"
},
"subject": {
"type": "_Application"
},
"condition": {
"cypher": "MATCH (subject:_Application) MATCH (car:Car)",
"filter": [
{
"operator": "AND",
"operands": [
{
"operator": "=",
"attribute": "subject.external_id",
"value": "$_appId",
"advice": {
"error_description": "subject external_id filter error"
}
},
{
"operator": "=",
"attribute": "car.external_id",
"value": "$carId"
}
]
}
]
},
"allowed_reads": {
"nodes": [
"car",
"car.*"
]
},
"allowed_upserts": {
"nodes": {
"existing_nodes": [
"car"
]
},
"relationships": {
"relationship_types": [
{
"type": "USES",
"source_node_label": "_Application",
"target_node_label": "Car"
}
]
}
}
}Json to create the CIQ Policy configuration using REST.
{
"project_id": "your_project_gid",
"description": "description of policy",
"display_name": "policy name",
"name": "policy-name",
"policy": "{\"meta\":{\"policy_version\":\"1.0-ciq\"},\"subject\":{\"type\":\"_Application\"},\"condition\":{\"cypher\":\"MATCH (subject:_Application) MATCH (car:Car)\",\"filter\":[{\"operator\":\"AND\",\"operands\":[{\"operator\":\"=\",\"attribute\":\"subject.external_id\",\"value\":\"$_appId\",\"advice\":{\"error_description\":\"subject external_id filter error\"}},{\"operator\":\"=\",\"attribute\":\"car.external_id\",\"value\":\"$carId\"}]}]},\"allowed_reads\":{\"nodes\":[\"car\",\"car.*\"]},\"allowed_upserts\":{\"nodes\":{\"existing_nodes\":[\"car\"]},\"relationships\":{\"relationship_types\":[{\"type\":\"USES\",\"source_node_label\":\"_Application\",\"target_node_label\":\"Car\"}]}}}",
"status": "ACTIVE",
"tags": []
}Json to read the CIQ Policy configuration using REST.
{
"id": "your_policy_configuration_gid"
}Step 3
The CIQ Query designates the Car nodes to be read.
{
"nodes": [
"car.external_id",
"car.property.model"
],
"relationships": []
}Json to create a CIQ Query configuration using REST.
{
"project_id": "your_project_gid",
"description": "description of knowledge query",
"display_name": "knowledge query name",
"name": "knowledge-query-name",
"policy_id": "your_policy_gid",
"query": "{\"nodes\":[\"car.external_id\",\"car.property.model\"],\"relationships\":[]}",
"status": "ACTIVE"
}Read the CIQ Query Configuration.
{
"id": "your_knowledge_query_configuration_gid"
}Step 4
Run a CIQ Execution to read a Car node.
{
"id": "knowledge_query_gid",
"input_params": {
"carId": "cadillacv16"
},
"page_token": 1
}CIQ Execution response.
{
"data": [
{
"nodes": {
"car.external_id": "cadillacv16",
"car.property.model": "V-16"
}
}
]
}Step 5
The CIQ Query designates the relationships USES to be upserted between the subject and a Car node.
{
"nodes": [
"car.external_id",
"car.property.model"
],
"relationships": [],
"upsert_relationships": [
{
"name": "newRel",
"source": "subject",
"target": "car",
"type": "USES",
"properties": [
{
"type": "status",
"value": "active"
}
]
}
]
}Json to create a CIQ Query configuration using REST.
{
"project_id": "your_project_gid",
"description": "description of knowledge query",
"display_name": "knowledge query name",
"name": "knowledge-query-name",
"policy_id": "your_policy_gid",
"query": "{\"nodes\":[\"car.external_id\",\"car.property.model\"],\"relationships\":[],\"upsert_relationships\":[{\"name\":\"newRel\",\"source\":\"subject\",\"target\":\"car\",\"type\":\"USES\",\"properties\":[{\"type\":\"status\",\"value\":\"active\"}]}]}",
"status": "ACTIVE"
}Read the CIQ Query Configuration.
{
"id": "your_knowledge_query_configuration_gid"
}Step 6
Run a CIQ Execution to upsert one relationship USES between the subject and a Car node.
{
"id": "knowledge_query_gid",
"input_params": {
"carId": "cadillacv16"
},
"page_token": 1
}CIQ Execution response.
{
"data": [
{
"nodes": {
"car.external_id": "cadillacv16",
"car.property.model": "V-16"
}
}
]
}Step 7
Create a CIQ Policy which designates the nodes which are allowed to be read and the nodes which are allowed to be upserted, according to the graph created previously.
The policy filters first on subject.external_id.
When the subject is _Application, the $_appId input does not need to be provided and is automatically assigned the subject.external_id value.
The policy also filters on car.external_id. The $carId input will need to be provided in the CIQ Execution.
The policy allows the Car nodes to be read, existing Car nodes to be upserted and new relationships between the subject and Car nodes to be upserted
{
"meta": {
"policy_version": "1.0-ciq"
},
"subject": {
"type": "_Application"
},
"condition": {
"cypher": "MATCH (subject:_Application)-[:USES]->(car:Car)",
"filter": [
{
"operator": "AND",
"operands": [
{
"operator": "=",
"attribute": "subject.external_id",
"value": "$_appId",
"advice": {
"error_description": "subject external_id filter error"
}
},
{
"operator": "=",
"attribute": "car.external_id",
"value": "$carId"
}
]
}
]
},
"allowed_reads": {
"nodes": [
"car",
"car.*"
]
},
"allowed_upserts": {
"nodes": {
"existing_nodes": [
"car"
]
},
"relationships": {
"relationship_types": [
{
"type": "USES",
"source_node_label": "_Application",
"target_node_label": "Car"
}
]
}
}
}Request to create the CIQ Policy configuration using REST.
{
"project_id": "your_project_gid",
"description": "description of policy",
"display_name": "policy name",
"name": "policy-name",
"policy": "{\"meta\":{\"policy_version\":\"1.0-ciq\"},\"subject\":{\"type\":\"_Application\"},\"condition\":{\"cypher\":\"MATCH (subject:_Application)-[:USES]->(car:Car)\",\"filter\":[{\"operator\":\"AND\",\"operands\":[{\"operator\":\"=\",\"attribute\":\"subject.external_id\",\"value\":\"$_appId\",\"advice\":{\"error_description\":\"subject external_id filter error\"}},{\"operator\":\"=\",\"attribute\":\"car.external_id\",\"value\":\"$carId\"}]}]},\"allowed_reads\":{\"nodes\":[\"car\",\"car.*\"]},\"allowed_upserts\":{\"nodes\":{\"existing_nodes\":[\"car\"]},\"relationships\":{\"relationship_types\":[{\"type\":\"USES\",\"source_node_label\":\"_Application\",\"target_node_label\":\"Car\"}]}}}",
"status": "ACTIVE",
"tags": []
}Request to read the CIQ Policy configuration using REST.
{
"id": "your_policy_configuration_gid"
}Step 8
The CIQ Query designates the Car nodes to be read.
{
"nodes": [
"car.external_id",
"car.property.model"
],
"relationships": []
}Json to create a CIQ Query configuration using REST.
{
"project_id": "your_project_gid",
"description": "description of knowledge query",
"display_name": "knowledge query name",
"name": "knowledge-query-name",
"policy_id": "your_policy_gid",
"query": "{\"nodes\":[\"car.external_id\",\"car.property.model\"],\"relationships\":[]}",
"status": "ACTIVE"
}Read the CIQ Query Configuration.
{
"id": "your_knowledge_query_configuration_gid"
}Step 9
Run a CIQ Execution to read a Car node.
{
"id": "knowledge_query_gid",
"input_params": {
"carId": "cadillacv16"
},
"page_token": 1
}CIQ Execution response in json format.
{
"data": [
{
"nodes": {
"car.external_id": "cadillacv16",
"car.property.model": "V-16"
}
}
]
}Step 10
Create a CIQ Policy which designates only the subject _Application and then the Car nodes which are allowed to be upserted.
The policy only filters first on subject.external_id.
When the subject is _Application, the $_appId input does not need to be provided and is automatically assigned the subject.external_id value.
The policy allows the subject node to be read, new Car nodes to be upserted and new relationships between the subject and Car nodes to be upserted
{
"meta": {
"policy_version": "1.0-ciq"
},
"subject": {
"type": "_Application"
},
"condition": {
"cypher": "MATCH (subject:_Application)",
"filter": [
{
"operator": "=",
"attribute": "subject.external_id",
"value": "$_appId"
}
]
},
"allowed_reads": {
"nodes": [
"subject",
"subject.*"
]
},
"allowed_upserts": {
"nodes": {
"node_types": [
"Car"
]
},
"relationships": {
"relationship_types": [
{
"type": "USES",
"source_node_label": "_Application",
"target_node_label": "Car"
}
]
}
}
}Json to create the CIQ Policy configuration using REST.
{
"project_id": "your_project_gid",
"description": "description of policy",
"display_name": "policy name",
"name": "policy-name",
"policy": "{\"meta\":{\"policy_version\":\"1.0-ciq\"},\"subject\":{\"type\":\"_Application\"},\"condition\":{\"cypher\":\"MATCH (subject:_Application)\",\"filter\":[{\"operator\":\"=\",\"attribute\":\"subject.external_id\",\"value\":\"$_appId\"}]},\"allowed_reads\":{\"nodes\":[\"subject\",\"subject.*\"]},\"allowed_upserts\":{\"nodes\":{\"node_types\":[\"Car\"]},\"relationships\":{\"relationship_types\":[{\"type\":\"USES\",\"source_node_label\":\"_Application\",\"target_node_label\":\"Car\"}]}}}",
"status": "ACTIVE",
"tags": []
}Json to read the CIQ Policy configuration using REST.
{
"id": "your_policy_configuration_gid"
}Step 11
The CIQ Query designates the Car nodes to be upserted.
{
"nodes": [
"car.external_id",
"car.property.model"
],
"relationships": [],
"upsert_nodes": [
{
"name": "car",
"type": "Car",
"external_id": "$carExtId",
"properties": [
{
"type": "model",
"value": "$model"
},
{
"type": "color",
"value": "$color"
}
]
}
],
"upsert_relationships": [
{
"name": "newRel",
"source": "subject",
"target": "car",
"type": "USES",
"properties": [
{
"type": "status",
"value": "active"
}
]
}
]
}Json to create a CIQ Query configuration using REST.
{
"project_id": "your_project_gid",
"description": "description of knowledge query",
"display_name": "knowledge query name",
"name": "knowledge-query-name",
"policy_id": "your_policy_gid",
"query": "{\"nodes\":[\"car.external_id\",\"car.property.model\"],\"relationships\":[],\"upsert_nodes\":[{\"name\":\"car\",\"type\":\"Car\",\"external_id\":\"$carExtId\",\"properties\":[{\"type\":\"model\",\"value\":\"$model\"},{\"type\":\"color\",\"value\":\"$color\"}]}],\"upsert_relationships\":[{\"name\":\"newRel\",\"source\":\"subject\",\"target\":\"car\",\"type\":\"USES\",\"properties\":[{\"type\":\"status\",\"value\":\"active\"}]}]}",
"status": "ACTIVE"
}Read the CIQ Query Configuration.
{
"id": "your_knowledge_query_configuration_gid"
}Step 12
Run a CIQ Execution to upsert a Car node.
{
"id": "knowledge_query_gid",
"input_params": {
"carExtId": "LightningMcqueen",
"model": "Corvette C6",
"color": "red"
},
"page_token": 1
}CIQ Execution response.
{
"data": [
{
"nodes": {
"car.external_id": "LightningMcqueen",
"car.property.model": "Corvette C6"
}
}
]
}