ContX IQ: With User node as a subject, read resources and upsert relationships and nodes.
Link a user access token with existing captured data and use this authorization to upsert data within the scope of a policy with a user as subject.
Use case
In this case, a user access token is sent and introspected to create a new User node, linked with a UserProfile node with a Member role in an Organization node.
Secondly, a user access token is sent and introspected to create a new User node, linked with a UserProfile node with an Admin role in an Organization node.
The Organization node is linked with Event nodes.
Then a READ query is executed on the UserProfile node with a Member role to verify that he can see the Event nodes.
Finally, a WRITE query is executed on the UserProfile node with an Admin role to create a new Event node and link it to the Organization.

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.
- Access tokens for the 2 UserProfile nodes
User Access tokens are sent in CIQ Execution in Headers: key:Authorization, value:Bearer token.
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 Subject nodes can be read, the User nodes can be upserted and relationships between User and UserProfile can be upserted.
3. Using the ServiceAccount credential as Bearer token, create a CIQ Query in the context of the policy to retrieve and upsert the data.
4. Using the AppAgent credential as API Key (name: X-IK-ClientKey), run a CIQ Execution to create a User node from the first access token and link it to the corresponding UserProfile.
5. Using the AppAgent credential as API Key (name: X-IK-ClientKey), run a CIQ Execution to create a User node from the second access token and link it to the corresponding UserProfile.
6. Using the ServiceAccount credential as Bearer token, create a CIQ Policy which designates the nodes which are allowed to read the Event nodes linked to the Organization nodes they have a relationship with, according to a specific role.
7. Using the ServiceAccount credential as Bearer token, create a CIQ Query in the context of the policy to retrieve data.
8. Using the AppAgent credential as API Key (name: X-IK-ClientKey), run a CIQ Execution to read the data.
9. Using the ServiceAccount credential as Bearer token, create a CIQ Policy which designates the nodes which are allowed to upsert Event nodes linked to the Organization nodes they have a relationship with, according to a specific role.
10. Using the ServiceAccount credential as Bearer token, create a CIQ Query in the context of the policy to upsert an Event node.
11. Using the AppAgent credential as API Key (name: X-IK-ClientKey), run a CIQ Execution to upsert an Event node.
Step 1
Ingest the nodes needed for this use case.
{
"nodes": [
{
"external_id": "alice",
"type": "UserProfile",
"properties": [
{
"type": "email",
"value": "alice@email.com"
}
]
},
{
"external_id": "bob",
"type": "UserProfile",
"properties": [
{
"type": "email",
"value": "bob@email.com"
}
]
},
{
"external_id": "org1",
"type": "Organization",
"properties": [
{
"type": "name",
"value": "Org1"
}
]
},
{
"external_id": "event_lambda",
"type": "Event",
"labels": [],
"is_identity": false,
"properties": [
{
"type": "title",
"value": "Event Lambda",
"metadata": {
"assurance_level": 1,
"source": "Some Source",
"verified_time": "2024-04-10T06:28:16Z"
}
},
{
"type": "startDate",
"value": "2025-01-01",
"metadata": {
"assurance_level": 1,
"source": "Some Source",
"verified_time": "2025-04-10T06:28:16Z"
}
},
{
"type": "link",
"value": "https://events.com",
"metadata": {
"assurance_level": 1,
"source": "Some Source",
"verified_time": "2025-04-10T06:28:16Z"
}
},
{
"type": "description",
"value": "Description ...",
"metadata": {
"assurance_level": 1,
"source": "Some Source",
"verified_time": "2025-04-10T06:28:16Z"
}
}
]
}
]
}Ingest the relationships needed for this use case.
{
"relationships": [
{
"source": {
"external_id": "alice",
"type": "UserProfile"
},
"target": {
"external_id": "org1",
"type": "Organization"
},
"type": "BELONGS_TO",
"properties": [
{
"type": "role",
"value": "Member"
}
]
},
{
"source": {
"external_id": "bob",
"type": "UserProfile"
},
"target": {
"external_id": "org1",
"type": "Organization"
},
"type": "BELONGS_TO",
"properties": [
{
"type": "role",
"value": "Admin"
}
]
},
{
"source": {
"external_id": "event_lambda",
"type": "Event"
},
"target": {
"external_id": "org1",
"type": "Organization"
},
"type": "PART_OF"
}
]
}Step 2
Create a CIQ Policy which designates the Subject nodes can be read,
the User nodes can be upserted and relationships between User and UserProfile can be upserted.
{
"meta": {
"policy_version": "1.0-ciq"
},
"subject": {
"type": "UserProfile"
},
"condition": {
"cypher": "MATCH (subject:UserProfile)",
"filter": [
{
"operator": "=",
"attribute": "subject.external_id",
"value": "$subject_external_id"
}
]
},
"allowed_reads": {
"nodes": [
"subject",
"subject.*"
]
},
"allowed_upserts": {
"nodes": {
"node_types": [
"User"
]
},
"relationships": {
"relationship_types": [
{
"type": "HAS",
"source_node_label": "UserProfile",
"target_node_label": "User"
}
]
}
}
}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\":\"UserProfile\"},\"condition\":{\"cypher\":\"MATCH (subject:UserProfile)\",\"filter\":[{\"operator\":\"=\",\"attribute\":\"subject.external_id\",\"value\":\"$subject_external_id\"}]},\"allowed_reads\":{\"nodes\":[\"subject\",\"subject.*\"]},\"allowed_upserts\":{\"nodes\":{\"node_types\":[\"User\"]},\"relationships\":{\"relationship_types\":[{\"type\":\"HAS\",\"source_node_label\":\"UserProfile\",\"target_node_label\":\"User\"}]}}}",
"status": "ACTIVE",
"tags": []
}Request to read the CIQ Policy configuration using REST.
{
"id": "your_policy_configuration_gid"
}Step 3
Create a CIQ Query in the context of the policy to retrieve and upsert the data.
{
"nodes": [
"subject",
"subject.property.email",
"user.property.email"
],
"relationships": [],
"upsert_nodes": [
{
"name": "user",
"type": "User",
"external_id": "$token.sub",
"properties": [
{
"type": "email",
"value": "$email"
}
]
}
],
"upsert_relationships": [
{
"name": "has",
"source": "subject",
"target": "user",
"type": "HAS"
}
]
}Request 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\":[\"subject\",\"subject.property.email\",\"user.property.email\"],\"relationships\":[],\"upsert_nodes\":[{\"name\":\"user\",\"type\":\"User\",\"external_id\":\"$token.sub\",\"properties\":[{\"type\":\"email\",\"value\":\"$email\"}]}],\"upsert_relationships\":[{\"name\":\"has\",\"source\":\"subject\",\"target\":\"user\",\"type\":\"HAS\"}]}",
"status": "ACTIVE"
}Read the CIQ Query Configuration.
{
"id": "your_knowledge_query_configuration_gid"
}Step 4
Run a CIQ Execution to create a User node from the first access token and link it to the corresponding UserProfile.
{
"id": "knowledge_query_gid",
"input_params": {
"subject_external_id": "alice",
"user_external_id": "alice_user_external_id",
"email": "alice@email.com"
},
"page_token": 1
}CIQ Execution response.
{
"data": [
{
"nodes": {
"subject": {
"Id": 14,
"ElementId": "4:0f1c76a0-92f1-4474-80af-aa4c317e636a:14",
"Labels": [
"Unique",
"Resource",
"UserProfile"
],
"Props": {
"_service": "capture-api",
"create_time": "2025-06-13T16:08:25.47Z",
"external_id": "alice",
"id": "4H1gEySmTGasbkjWDyyuXg",
"type": "UserProfile",
"update_time": "2025-06-13T16:08:25.47Z"
}
},
"subject.property.email": "alice@email.com",
"user.property.email": "alice@email.com"
}
}
]
}Step 5
Run a CIQ Execution to create a User node from the second access token and link it to the corresponding UserProfile.
{
"id": "knowledge_query_gid",
"input_params": {
"subject_external_id": "bob",
"user_external_id": "bob_user_external_id",
"email": "bob@email.com"
},
"page_token": 1
}CIQ Execution response.
{
"data": [
{
"nodes": {
"subject": {
"Id": 15,
"ElementId": "4:0f1c76a0-92f1-4474-80af-aa4c317e636a:15",
"Labels": [
"Unique",
"Resource",
"UserProfile"
],
"Props": {
"_service": "capture-api",
"create_time": "2025-06-13T16:08:25.47Z",
"external_id": "bob",
"id": "lIHALUiJSSiwVCff51KxxA",
"type": "UserProfile",
"update_time": "2025-06-13T16:08:25.47Z"
}
},
"subject.property.email": "bob@email.com",
"user.property.email": "bob@email.com"
}
}
]
}Step 6
Create a CIQ Policy which designates the nodes which are allowed to read the Event nodes linked to the Organization nodes they have a relationship with, according to a specific role.
{
"meta": {
"policy_version": "1.0-ciq"
},
"subject": {
"type": "UserProfile"
},
"condition": {
"cypher": "MATCH (user:User)<-[:HAS]-(subject:UserProfile)-[bt:BELONGS_TO]->(org:Organization)<-[:PART_OF]-(event:Event)",
"filter": [
{
"operator": "AND",
"operands": [
{
"operator": "=",
"attribute": "subject.external_id",
"value": "$subject_external_id"
},
{
"operator": "=",
"attribute": "user.external_id",
"value": "$token.sub"
},
{
"operator": "=",
"attribute": "bt.role",
"value": "Member"
}
]
}
]
},
"allowed_reads": {
"nodes": [
"event",
"event.*",
"org.external_id",
"subject.property.name"
]
}
}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\":\"UserProfile\"},\"condition\":{\"cypher\":\"MATCH (user:User)<-[:HAS]-(subject:UserProfile)-[bt:BELONGS_TO]->(org:Organization)<-[:PART_OF]-(event:Event)\",\"filter\":[{\"operator\":\"AND\",\"operands\":[{\"operator\":\"=\",\"attribute\":\"subject.external_id\",\"value\":\"$subject_external_id\"},{\"operator\":\"=\",\"attribute\":\"user.external_id\",\"value\":\"$token.sub\"},{\"operator\":\"=\",\"attribute\":\"bt.role\",\"value\":\"Member\"}]}]},\"allowed_reads\":{\"nodes\":[\"event\",\"event.*\",\"org.external_id\",\"subject.property.name\"]}}",
"status": "ACTIVE",
"tags": []
}Json to read the CIQ Policy configuration using REST.
{
"id": "your_policy_configuration_gid"
}Step 7
Create a CIQ Query in the context of the policy to retrieve data.
{
"nodes": [
"event"
],
"filter": {
"attribute": "subject.property.email",
"operator": "=",
"value": "$email"
}
}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\":[\"event\"],\"filter\":{\"attribute\":\"subject.property.email\",\"operator\":\"=\",\"value\":\"$email\"}}",
"status": "ACTIVE"
}Read the CIQ Query Configuration.
{
"id": "your_knowledge_query_configuration_gid"
}Step 8
Run a CIQ Execution to read the data.
{
"id": "knowledge_query_gid",
"input_params": {
"email": "alice@email.com",
"subject_external_id": "alice"
},
"page_token": 1
}CIQ Execution response.
{
"data": [
{
"nodes": {
"event": {
"Id": 8,
"ElementId": "4:0f1c76a0-92f1-4474-80af-aa4c317e636a:8",
"Labels": [
"Unique",
"Resource",
"Event"
],
"Props": {
"_service": "capture-api",
"create_time": "2025-06-13T16:08:11.293Z",
"external_id": "event_lambda",
"id": "ABeHsubWR7a3Yj0lOSuKRA",
"type": "Event",
"update_time": "2025-06-13T16:08:11.293Z"
}
}
}
}
]
}Step 9
Create a CIQ Policy which designates the nodes which are allowed to upsert Event nodes linked to the Organization nodes they have a relationship with, according to a specific role.
{
"meta": {
"policy_version": "1.0-ciq"
},
"subject": {
"type": "UserProfile"
},
"condition": {
"cypher": "MATCH (user:User)<-[:HAS]-(subject:UserProfile)-[bt:BELONGS_TO]->(org:Organization)",
"filter": [
{
"operator": "AND",
"operands": [
{
"operator": "=",
"attribute": "subject.external_id",
"value": "$profile_external_id"
},
{
"operator": "=",
"attribute": "$token.sub",
"value": "$user_external_id"
},
{
"operator": "=",
"attribute": "bt.role",
"value": "Admin"
}
]
}
]
},
"allowed_reads": {
"nodes": [
"org.external_id",
"subject.property.name"
]
},
"allowed_upserts": {
"nodes": {
"node_types": [
"Event"
]
},
"relationships": {
"relationship_types": [
{
"type": "PART_OF",
"source_node_label": "Event",
"target_node_label": "Organization"
}
]
}
}
}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\":\"UserProfile\"},\"condition\":{\"cypher\":\"MATCH (user:User)<-[:HAS]-(subject:UserProfile)-[bt:BELONGS_TO]->(org:Organization)\",\"filter\":[{\"operator\":\"AND\",\"operands\":[{\"operator\":\"=\",\"attribute\":\"subject.external_id\",\"value\":\"$profile_external_id\"},{\"operator\":\"=\",\"attribute\":\"$token.sub\",\"value\":\"$user_external_id\"},{\"operator\":\"=\",\"attribute\":\"bt.role\",\"value\":\"Admin\"}]}]},\"allowed_reads\":{\"nodes\":[\"org.external_id\",\"subject.property.name\"]},\"allowed_upserts\":{\"nodes\":{\"node_types\":[\"Event\"]},\"relationships\":{\"relationship_types\":[{\"type\":\"PART_OF\",\"source_node_label\":\"Event\",\"target_node_label\":\"Organization\"}]}}}",
"status": "ACTIVE",
"tags": []
}Json to read the CIQ Policy configuration using REST.
{
"id": "your_policy_configuration_gid"
}Step 10
Create a CIQ Query in the context of the policy to upsert an Event node.
{
"nodes": [
"event",
"event.property.title",
"event.property.link"
],
"relationships": [],
"upsert_nodes": [
{
"name": "event",
"type": "Event",
"external_id": "$eventId",
"properties": [
{
"type": "title",
"value": "$title"
},
{
"type": "link",
"value": "$link"
}
]
}
],
"upsert_relationships": [
{
"name": "part",
"source": "event",
"target": "org",
"type": "PART_OF"
}
]
}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\":[\"event\",\"event.property.title\",\"event.property.link\"],\"relationships\":[],\"upsert_nodes\":[{\"name\":\"event\",\"type\":\"Event\",\"external_id\":\"$eventId\",\"properties\":[{\"type\":\"title\",\"value\":\"$title\"},{\"type\":\"link\",\"value\":\"$link\"}]}],\"upsert_relationships\":[{\"name\":\"part\",\"source\":\"event\",\"target\":\"org\",\"type\":\"PART_OF\"}]}",
"status": "ACTIVE"
}Read the CIQ Query Configuration.
{
"id": "your_knowledge_query_configuration_gid"
}Step 11
Run a CIQ Execution to upsert an Event node.
{
"id": "knowledge_query_gid",
"input_params": {
"profile_external_id": "bob",
"user_external_id": "bob_user_external_id",
"eventId": "event14",
"title": "Event in the parking lot",
"link": "https://www.example.com"
},
"page_token": 1
}CIQ Execution response.
{
"data": [
{
"nodes": {
"event": {
"Id": 24,
"ElementId": "4:0f1c76a0-92f1-4474-80af-aa4c317e636a:24",
"Labels": [
"Unique",
"Resource",
"Event"
],
"Props": {
"create_time": "2025-06-13T16:23:53.388Z",
"external_id": "event14",
"id": "sYE-gBnaRQeRO6gZdHA59A",
"type": "Event",
"update_time": "2025-06-13T16:23:53.388Z"
}
},
"event.property.link": "https://www.example.com",
"event.property.title": "Event in the parking lot"
}
}
]
}