Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
100 changes: 100 additions & 0 deletions en/asgardeo/docs/guides/customer-data/concepts/profile-attributes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Profile attributes

**Profile attributes** define the shape of data that can be stored on a profile for your organization. They control attribute names, types, mutability, and how values are resolved when two profiles are merged.

Together, the set of profile attributes defined for your organization makes up the **profile attribute schema**.

---

## Scopes

Profile attributes are organised into three scopes:

| Scope | Description |
|---|---|
| `identity_attributes` | Attributes sourced from the identity system (e.g. email, phone, name from {{ product_name }} claims) |
| `traits` | Behavioural or preference data managed by the application (e.g. language, segments) |
| `application_data` | Per-application attributes, scoped by application identifier |

---

## Attribute fields

| Field | Required | Description |
|---|---|---|
| `attribute_name` | yes | Dot-notation path including scope prefix |
| `display_name` | no | Human-readable label |
| `value_type` | yes | One of the supported data types (see below) |
| `merge_strategy` | yes | How to resolve the value when two profiles are merged |
| `mutability` | yes | Read/write behaviour (see below) |
| `multi_valued` | no | If `true`, the attribute holds an array of the declared type |
| `canonical_values` | no | Enumerated allowed values (for string attributes) |
| `sub_attributes` | no | Child attributes when `value_type` is `complex` |
| `application_identifier` | no | Scopes the attribute to a specific application (for `application_data`) |

---

## Supported value types

| Type | Description |
|---|---|
| `string` | Plain text |
| `integer` | Whole number |
| `decimal` | Floating-point number |
| `boolean` | `true` / `false` |
| `date` | Calendar date |
| `date_time` | Date and time |
| `epoch` | Unix timestamp (milliseconds) |
| `complex` | Nested object, define child fields in `sub_attributes` |

---

## Mutability

Mutability controls whether an attribute value can be changed once set.

| Value | Meaning |
|---|---|
| `readWrite` | Can be freely read and updated |
| `readOnly` | System-managed, cannot be updated by applications (e.g. `meta.created_at`) |
| `writeOnly` | Can be written but not read back |
| `immutable` | Must be set at creation, cannot be changed (e.g. `profile_id`) |
| `writeOnce` | Can be empty initially; once set, cannot be updated (e.g. `user_id`) |

---

## Merge strategies

When two profiles are unified, the merge strategy for each attribute decides which value wins.

| Strategy | Behaviour |
|---|---|
| `overwrite` | The incoming profile's value replaces the existing one |
| `combine` | Both values are combined into an array (requires `multi_valued: true`) |

---

## Core attributes

These attributes are built into every profile and cannot be modified:

| Attribute | Type | Mutability |
|---|---|---|
| `profile_id` | `string` | `immutable` |
| `user_id` | `string` | `writeOnce` |
| `meta.created_at` | `date_time` | `readOnly` |
| `meta.updated_at` | `date_time` | `readOnly` |
| `meta.location` | `string` | `readOnly` |

---

## Staying in sync with {{ product_name }}

`identity_attributes` mirror the claim dialects in {{ product_name }}. When a claim is added, updated, or deleted, the service automatically reconciles its local attribute set so the two stay aligned, no manual action is needed.

---

## Related

- [Manage profile attributes]({{base_path}}/guides/customer-data/guides/manage-profile-attributes)
- [Unification rules]({{base_path}}/guides/customer-data/concepts/unification-rules)
1 change: 1 addition & 0 deletions en/asgardeo/docs/guides/customer-data/concepts/profiles.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% include "../../../../../includes/guides/customer-data/concepts/profiles.md" %}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% include "../../../../../includes/guides/customer-data/concepts/unification-rules.md" %}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% include "../../../../includes/guides/customer-data/enable-customer-data-service.md" %}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% include "../../../../../includes/guides/customer-data/guides/manage-profile-attributes.md" %}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% include "../../../../../includes/guides/customer-data/guides/manage-unification-rules.md" %}
1 change: 1 addition & 0 deletions en/asgardeo/docs/guides/customer-data/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% include "../../../../includes/guides/customer-data/index.md" %}
13 changes: 13 additions & 0 deletions en/asgardeo/features.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,18 @@
"guides/webhooks/setup-webhooks.md",
"guides/webhooks/webhook-events-and-payloads.md"
]
},

"customer_data_service": {
"enabled": true,
"page": [
"guides/customer-data/index.md",
"guides/customer-data/enable-customer-data-service.md",
"guides/customer-data/concepts/profiles.md",
"guides/customer-data/concepts/profile-attributes.md",
"guides/customer-data/concepts/unification-rules.md",
"guides/customer-data/guides/manage-profile-attributes.md",
"guides/customer-data/guides/manage-unification-rules.md"
]
}
}
13 changes: 13 additions & 0 deletions en/asgardeo/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ theme:
extra:
base_path: /asgardeo/docs
product: asgardeo
nav_chip:
Customer Data:
type: Preview
content:
sdkconfig:
baseUrl: "https://api.asgardeo.io/t/<your-organization-name>"
Expand Down Expand Up @@ -577,6 +580,16 @@ nav:
- Approval workflows: guides/workflows/approval-workflows.md
- Approval workflow rules: guides/workflows/workflow-rules.md
- Workflow requests: guides/workflows/workflow-requests.md
- Customer Data:
- Customer Data: guides/customer-data/index.md
- Enable Customer Data Service: guides/customer-data/enable-customer-data-service.md
- Concepts:
- Profiles: guides/customer-data/concepts/profiles.md
- Profile attributes: guides/customer-data/concepts/profile-attributes.md
- Unification rules: guides/customer-data/concepts/unification-rules.md
- Manage:
- Manage profile attributes: guides/customer-data/guides/manage-profile-attributes.md
- Manage unification rules: guides/customer-data/guides/manage-unification-rules.md
- Account configurations:
- Account configurations: guides/account-configurations/index.md
- Login security:
Expand Down
52 changes: 52 additions & 0 deletions en/includes/guides/customer-data/concepts/profiles.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{% if product == "asgardeo" %}

# Profiles

A **profile** is the central entity in the Customer Data Service. It represents a single person's collected data, their identity attributes, behavioural traits, and per application data unified across all interactions.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Hyphenate compound modifier.

"per application data" should be hyphenated as "per-application data" when used as a compound modifier before a noun. As per coding guidelines, technical writing should follow standard grammar conventions.

Suggested fix
-A **profile** is the central entity in the Customer Data Service. It represents a single person's collected data, their identity attributes, behavioural traits, and per application data unified across all interactions.
+A **profile** is the central entity in the Customer Data Service. It represents a single person's collected data, their identity attributes, behavioural traits, and per-application data unified across all interactions.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
A **profile** is the central entity in the Customer Data Service. It represents a single person's collected data, their identity attributes, behavioural traits, and per application data unified across all interactions.
A **profile** is the central entity in the Customer Data Service. It represents a single person's collected data, their identity attributes, behavioural traits, and per-application data unified across all interactions.
🧰 Tools
🪛 LanguageTool

[grammar] ~5-~5: Use a hyphen to join words.
Context: ... attributes, behavioural traits, and per application data unified across all inte...

(QB_NEW_EN_HYPHEN)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@en/includes/guides/customer-data/concepts/profiles.md` at line 5, Change the
phrase "per application data" to the hyphenated compound modifier
"per-application data" in the profiles description sentence in profiles.md (the
line containing "A **profile** is the central entity... per application data
unified across all interactions."). Ensure the updated sentence reads
"...behavioural traits, and per-application data unified across all
interactions." to follow compound modifier grammar rules.


![Profile List]({{base_path}}/assets/img/guides/customer-data/profile-list.png){: width="auto" style="display: block; margin: 0;"}

---

## Temporary vs permanent profiles

Check warning on line 11 in en/includes/guides/customer-data/concepts/profiles.md

View workflow job for this annotation

GitHub Actions / Vale style check

[vale] reported by reviewdog 🐶 [WSO2-IAM.SentenceStyleTitles] 'Temporary vs permanent profiles' should use sentence-style capitalization. Raw Output: {"message": "[WSO2-IAM.SentenceStyleTitles] 'Temporary vs permanent profiles' should use sentence-style capitalization.", "location": {"path": "en/includes/guides/customer-data/concepts/profiles.md", "range": {"start": {"line": 11, "column": 4}}}, "severity": "INFO"}

Profiles are either **temporary** (anonymous) or **permanent** (identified).

### Temporary profile

- Created when an anonymous user first interacts (e.g. visits a website)
- Has no `user_id`
- Linked to a browser cookie (`cds_profile`)
- Accumulates behavioural data during the anonymous session

### Permanent profile

- Has a `user_id`, which is set when the user logs in or is created in {{ product_name }}
- Acts as the master record for that identity
- May have one or more temporary profiles merged into it over time

---

## Profile structure

| Field | Description |
|---|---|
| `profile_id` | System generated UUID. Immutable. |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Hyphenate compound modifier.

"System generated" should be hyphenated as "System-generated" when used as a compound modifier.

Suggested fix
-| `profile_id` | System generated UUID. Immutable. |
+| `profile_id` | System-generated UUID. Immutable. |
🧰 Tools
🪛 LanguageTool

[grammar] ~34-~34: Use a hyphen to join words.
Context: ...tion | |---|---| | profile_id | System generated UUID. Immutable. | | user_id...

(QB_NEW_EN_HYPHEN)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@en/includes/guides/customer-data/concepts/profiles.md` at line 34, Update the
table cell for `profile_id` to hyphenate the compound modifier: change "System
generated UUID. Immutable." to "System-generated UUID. Immutable." so the
modifier "System-generated" correctly applies to "UUID" (locate the table row
containing `profile_id`).

| `user_id` | The user's ID from {{ product_name }}. Empty on anonymous profiles. |
| `identity_attributes` | Attributes sourced from the identity system (e.g. email, phone, name). Keyed by attribute name. |
| `traits` | Behavioural or preference data (e.g. download count, segment tags). |
| `application_data` | Per-application data, keyed by application identifier. |
| `meta.created_at` | When the profile was created. Read-only. |
| `meta.updated_at` | When the profile was last modified. Read-only. |
| `merged_from` | References to profiles that were unified into this one. |
| `merged_to` | Set on child profiles, points to the master profile they were merged into. |

![Profile Structure]({{base_path}}/assets/img/guides/customer-data/profile-structure.png){: width="auto" style="display: block; margin: 0;"}

---

## Related

- [Profile attributes]({{base_path}}/guides/customer-data/concepts/profile-attributes)
- [Unification rules]({{base_path}}/guides/customer-data/concepts/unification-rules)
{% endif %}
44 changes: 44 additions & 0 deletions en/includes/guides/customer-data/concepts/unification-rules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{% if product == "asgardeo" %}

# Unification rules

**Unification rules** tell the Customer Data Service when two separate profiles should be recognised as the same person and merged. Each rule specifies a profile attribute to match on, if two profiles share the same value for that attribute, they are candidates for merging.

---

## Rule structure

| Field | Description |
|---|---|
| `rule_name` | Human-readable name. Also recorded as the reason on a merge. |
| `property_name` | The attribute name to match on (e.g. `identity_attributes.email`) |
| `priority` | Lower number = evaluated first. Rules are sorted ascending by priority. |
| `is_active` | Only active rules are evaluated during unification |

---

## How rules are evaluated

When a profile is created or updated, the service queues it for unification. The unification worker:

1. Fetches all active rules for the organization, sorted by `priority` ascending.
2. For each rule, checks whether any existing master profile has the same value for `property_name` as the incoming profile.
3. On the first match, merges the two profiles and stops, only one rule fires per unification run.

Rules are evaluated **after** the system level `userId` match. If two profiles share the same `userId`, they are always merged regardless of any rules.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Hyphenate compound modifier.

"system level" should be hyphenated as "system-level" when used as a compound modifier.

Suggested fix
-Rules are evaluated **after** the system level `userId` match. If two profiles share the same `userId`, they are always merged regardless of any rules.
+Rules are evaluated **after** the system-level `userId` match. If two profiles share the same `userId`, they are always merged regardless of any rules.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Rules are evaluated **after** the system level `userId` match. If two profiles share the same `userId`, they are always merged regardless of any rules.
Rules are evaluated **after** the system-level `userId` match. If two profiles share the same `userId`, they are always merged regardless of any rules.
🧰 Tools
🪛 LanguageTool

[grammar] ~28-~28: Use a hyphen to join words.
Context: ...Rules are evaluated after the system level userId match. If two profiles sh...

(QB_NEW_EN_HYPHEN)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@en/includes/guides/customer-data/concepts/unification-rules.md` at line 28,
Change the phrase "system level `userId` match" to use a hyphenated compound
modifier: replace "system level `userId` match" with "system-level `userId`
match" in the sentence that reads "Rules are evaluated **after** the system
level `userId` match. If two profiles..." so the doc uses the correct compound
adjective form.


---

## Priority guidance

- Assign **lower** priority numbers to high-confidence identifiers (e.g. `identity_attributes.email` at priority 1).
- Assign **higher** priority numbers to weaker signals (e.g. `traits.phone` at priority 10).
- Leave gaps between priorities (e.g. 10, 20, 30) so new rules can be inserted without reordering.

---

## Related

- [Manage unification rules]({{base_path}}/guides/customer-data/guides/manage-unification-rules)
- [Profile attributes]({{base_path}}/guides/customer-data/concepts/profile-attributes)
{% endif %}
34 changes: 34 additions & 0 deletions en/includes/guides/customer-data/enable-customer-data-service.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{% if product == "asgardeo" %}
<h1>Enable Customer Data Service <div class="md-chip md-chip--preview"><span class="md-chip__label">Preview</span></div></h1>

!!! Note

The Customer Data Service is currently in **Preview**. Some features may be subject to changes in future releases.

The Customer Data Service is hidden behind Feature Preview while in Preview. Once you enable it for your organization, a new **Customer Data** entry appears in the left navigation pane.

## Enable from Feature Preview

Check warning on line 10 in en/includes/guides/customer-data/enable-customer-data-service.md

View workflow job for this annotation

GitHub Actions / Vale style check

[vale] reported by reviewdog 🐶 [WSO2-IAM.SentenceStyleTitles] 'Enable from Feature Preview' should use sentence-style capitalization. Raw Output: {"message": "[WSO2-IAM.SentenceStyleTitles] 'Enable from Feature Preview' should use sentence-style capitalization.", "location": {"path": "en/includes/guides/customer-data/enable-customer-data-service.md", "range": {"start": {"line": 10, "column": 4}}}, "severity": "INFO"}

1. Click on the user dropdown in the top right corner.
2. Select **Feature Preview**.
3. In the feature preview dialog, toggle **Customer Data Service** to **Enabled** and close the dialog.
4. **Customer Data** now appears in the left navigation pane.

![Enable Customer Data Service from Feature Preview]({{base_path}}/assets/img/guides/customer-data/feature-preview-cds-on.png){: width="auto" style="display: block; margin: 0;"}

## Disable Customer Data Service

Check warning on line 19 in en/includes/guides/customer-data/enable-customer-data-service.md

View workflow job for this annotation

GitHub Actions / Vale style check

[vale] reported by reviewdog 🐶 [WSO2-IAM.SentenceStyleTitles] 'Disable Customer Data Service' should use sentence-style capitalization. Raw Output: {"message": "[WSO2-IAM.SentenceStyleTitles] 'Disable Customer Data Service' should use sentence-style capitalization.", "location": {"path": "en/includes/guides/customer-data/enable-customer-data-service.md", "range": {"start": {"line": 19, "column": 4}}}, "severity": "INFO"}

To turn the feature off again:

1. Click on the user dropdown in the top right corner.
2. Select **Feature Preview**.
3. Toggle **Customer Data Service** to **Disabled** and close the dialog.

The **Customer Data** entry is removed from the left navigation pane. Existing profile, attribute, and unification rule data is preserved while the feature is in Preview.

## Next steps

- Learn what a [Profile]({{base_path}}/guides/customer-data/concepts/profiles) is and how anonymous activity gets attached to a user.
- Review the [Profile attributes]({{base_path}}/guides/customer-data/concepts/profile-attributes) defined for your organization.
- Configure [Unification rules]({{base_path}}/guides/customer-data/concepts/unification-rules) that decide when two profiles should be merged.
{% endif %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{% if product == "asgardeo" %}

# Manage profile attributes

Profile attributes control which fields can be stored on a profile and how they behave. Manage them from **Customer Data****Profile Attributes** in the console.

For a conceptual overview of attribute types, mutability, and merge strategies see [Profile attributes]({{base_path}}/guides/customer-data/concepts/profile-attributes).

---

## View profile attributes

1. From the console, go to **Customer Data****Profile Attributes**.
2. The list shows every attribute defined for your organization, grouped by scope (`identity_attributes`, `traits`, `application_data`).

Attributes sourced from {{ product_name }} claims appear under `identity_attributes` and are managed by the system — their type and mutability are read-only.

![Profile Attribute View]({{base_path}}/assets/img/guides/customer-data/profile-attribute-view.png){: width="auto" style="display: block; margin: 0;"}

---

## Add an attribute

1. Click **New attribute**.
2. Fill in:
- **Attribute name** — including the scope prefix (e.g. `traits.preferred_language`).
- **Display name** — optional, human-readable label.
- **Value type** — see [supported value types]({{base_path}}/guides/customer-data/concepts/profile-attributes#supported-value-types).
- **Mutability** — controls whether the value can be changed once set.
- **Merge strategy**`overwrite` or `combine`. Choose `combine` for attributes where both pre- and post-merge values should be retained (e.g. interest tags).
- **Multi-valued** — required when using `combine`.
- **Canonical values** — optional, for enumerated string values.
- **Application identifier** — required for `application_data` attributes.
3. Click **Save**.

![Scopes]({{base_path}}/assets/img/guides/customer-data/scopes.gif){: width="auto" style="display: block; margin: 0;"}

---

## Edit an attribute

1. Click an attribute in the list.
2. Update the fields you want to change.
3. Click **Save**.

Attributes synced from {{ product_name }} cannot be edited from here — change the corresponding claim in {{ product_name }} and the attribute set will reflect it automatically.

---

## Delete an attribute

1. Click the attribute, then click **Delete**.
2. Confirm the deletion.

Existing profile data stored under the attribute is dropped.

---

## What happens when you change `merge_strategy`

`merge_strategy` is applied on **future** unification runs only. Existing master profiles are not re-merged when you change the strategy.

If you switch a single-valued attribute to `combine`, also set **Multi-valued** to `true` — otherwise the merge will fall back to `overwrite`.

---

## Related

- [Profile attributes]({{base_path}}/guides/customer-data/concepts/profile-attributes) — concepts and field reference.
- [Unification rules]({{base_path}}/guides/customer-data/concepts/unification-rules) — rules match on the attributes defined here.
{% endif %}
Loading
Loading