diff --git a/.claude/skills/docs-writing.md b/.claude/skills/docs-writing.md index 957dad9e..d08927ed 100644 --- a/.claude/skills/docs-writing.md +++ b/.claude/skills/docs-writing.md @@ -111,6 +111,7 @@ Sidebar grouping in `docs.json` is independent of folder structure. You can visu - **Optional sections**: Use `## Optional: Section name` for entire optional tasks or sections - **UI elements**: Bold formatting (**New profile**) - **Navigation paths**: **Admin** > **Access profiles** > **New profile** +- **Kebab/overflow menus**: Always write as the **...** (more actions) menu — e.g., "click the **...** (more actions) menu and select **Delete**." This is the established pattern across the docs; don't substitute "kebab menu," "more options," a middle-dot glyph (···), or a vertical ellipsis (⋮). - **Terminology**: Use product-specific terms consistently (access profile, entitlement, campaign) - **Clarity**: Be specific, cite sources, avoid vague claims - **Simplicity**: Keep examples practical, avoid excessive options diff --git a/docs.json b/docs.json index 31d42e19..5942af90 100644 --- a/docs.json +++ b/docs.json @@ -141,7 +141,8 @@ "group": "Credentials & vaulting", "pages": [ "product/admin/vaults", - "product/admin/secret-sharing" + "product/admin/secret-sharing", + "product/admin/decoys" ] }, { @@ -307,7 +308,8 @@ "pages": [ "product/admin/query", "product/admin/inventory", - "product/admin/external-insights" + "product/admin/external-insights", + "product/admin/findings" ] }, { diff --git a/product/admin/decoys.mdx b/product/admin/decoys.mdx new file mode 100644 index 00000000..fe60073e --- /dev/null +++ b/product/admin/decoys.mdx @@ -0,0 +1,88 @@ +--- +title: "Decoys" +og:title: "Decoys" +og:description: "Plant tripwire credentials that look real but grant no access, and turn any attempt to use one into a Critical finding." +description: "Plant tripwire credentials that look real but grant no access, and turn any attempt to use one into a Critical finding." +--- +{/* Editor Refresh: 2026-08-13 */} + + +**Early access.** This feature is in early access, which means it's undergoing ongoing testing and development while we gather feedback, validate functionality, and improve outputs. Share feedback with the C1 Support team. + + +Plant a credential that looks real but grants no access. Any attempt to use it is a high-confidence signal that someone has stolen access. Decoys are tripwire credentials. Plant them where an attacker would look — env files, CI variables, secret managers. Using one raises a [Critical finding](/product/admin/findings). + +Managing decoys requires the **Super Administrator** role in C1. Go to **Settings** > **Security** > **Decoys** to get started. + +## Plant a decoy + +C1 supports five decoy types, each shaped to sit alongside a different kind of real credential: + +| Decoy type | What it plants | +| :--- | :--- | +| Human user credential | Client ID + secret planted under an existing human user. | +| Service principal credential | Client ID + secret planted under an existing service principal. | +| Connector client credential | Client ID + secret shaped like a connector credential. C1 places it under your tenant's C1 app — there's no app or connector to choose. | +| Workload federation trust | A trust under an existing workload federation provider. Any signature-valid JWT matching its condition triggers a finding. | +| Access token | A long-lived API access token issued for an existing user. | + +Every decoy type except a connector client credential plants under an existing object — a human user, a service principal, or a registered workload federation provider. C1 places connector client credentials automatically, with nothing to choose. For every other type, make sure the object you need already exists before you start. + + + +Go to **Decoys**. + + +Click **Add decoy**. + + +Choose a decoy type. + + +For a workload federation trust, also set a **Condition expression** — a CEL expression evaluated against the presented JWT's claims. For example: `claims.sub.startsWith("repo:acme/fake-infra:")`. + + +Set a **Display name**. + + +**Optional.** Set a **Description** to remind yourself where you planted it. + + +**Optional.** Add **Annotations** — key/value tags for filtering, reporting, and integrations, for example `team = platform` or `owner = alice`. Annotations carry over onto the finding a decoy produces. A [routing rule](/product/admin/findings#routing-rules) can then condition on them. + + +Click **Plant decoy**. + + + +C1 shows the decoy's credential material — a client ID and secret, an access token, or a workload federation trust ID, depending on the type. It also shows a fingerprint. + + +This is the only time C1 shows this credential material. Save it now: copy each value or download the `.env` file. You'll need to confirm you've saved it before this screen closes. If you lose it, rotate the decoy to get a new one. + + +Save the fingerprint alongside wherever you place the secret. It's how you'll recognize which planted copy fired when you see the resulting finding. + +## Manage a decoy + +Open a decoy from the list to edit its display name, description, or annotations, or to take one of the following actions from the **...** (more actions) menu: + +- **Disable** — stops the decoy from triggering findings without deleting it. Past findings stay in history. You can re-enable it at any time. +- **Rotate** — mints a new secret for the decoy and invalidates the old one. C1 shows the new credential material once, the same as when you first planted it. +- **Delete** — removes the decoy from the list and stops it from triggering findings. Past findings stay in history. + +## What happens when a decoy is used + +Any attempt to authenticate with a planted decoy credential triggers two things. Whoever presented it gets an ordinary authentication failure — there's no way to tell a decoy apart from a real bad credential. C1 also records the attempt. + +If the **Decoy credential used** [finding type](/product/admin/findings#turn-on-finding-types) is turned on, C1 raises a Critical finding the moment the decoy is used. Repeated use of the same decoy doesn't create duplicate findings — it's tracked as recurrences of the same finding. If the finding had been resolved, it reopens. + + +Turning off the **Decoy credential used** finding type stops the finding from being created. C1 still records every use to your audit log regardless. Quieting the finding doesn't cost you the trail. + + +The resulting finding includes an **Attempts** table with the forensic detail you need for incident response — timestamp, source IP, user agent, and endpoint for every attempt. Each row also includes the raw event detail behind it. + +If a decoy's secret turns up published somewhere public — a paste site, a public repository — C1 raises a separate **Decoy publicly exposed** finding. The finding includes the scanner that found it, where it was found, and when. + +See [Findings](/product/admin/findings) for how to turn on these finding types and build rules around them. diff --git a/product/admin/findings.mdx b/product/admin/findings.mdx new file mode 100644 index 00000000..dd9626e7 --- /dev/null +++ b/product/admin/findings.mdx @@ -0,0 +1,161 @@ +--- +title: "Findings" +og:title: "Findings" +og:description: "Detect and act on the things you care about in your organization's access data, from unowned service accounts to exposed credentials." +description: "Detect and act on the things you care about in your organization's access data, from unowned service accounts to exposed credentials." +--- +{/* Editor Refresh: 2026-08-13 */} + + +**Early access.** This feature is in early access, which means it's undergoing ongoing testing and development while we gather feedback, validate functionality, and improve outputs. Share feedback with the C1 Support team. + + +Stop hunting for risk by hand. Point C1 at the conditions you care about — unowned service accounts, exposed credentials, misclassified identities, and more. It surfaces them as findings the moment they occur, and rules let you triage, escalate, or resolve them automatically. C1 checks for these conditions every time a connector syncs. It reports back the moment it detects a match. + +Go to **Identity security** > **Findings** to get started. + +## Turn on finding types + +C1 ships with a catalog of built-in finding types, grouped by category. None are required — you choose which conditions matter to your organization. + + +Findings don't appear until you turn on the finding types you want C1 to detect. There's no separate "create" or "new" control — everything starts from **Findings settings**. + + + + +From any tab in **Findings**, click the **settings** (gear) icon in the top right. + + +In **Findings settings**, toggle on the finding types you want C1 to detect. Each type shows a short description of what it looks for. + + +Click **Save changes**. + + + +C1 starts creating findings of the types you turned on the next time each connector syncs. + + +Turning off a finding type stops C1 from creating new findings of that type. Findings of that type that are already open stay open — nothing re-checks them, so they won't resolve automatically. + + +### Finding catalog reference + +The following finding types are available today, grouped by category: + +| Category | Finding type | Detects | +| :--- | :--- | :--- | +| Ownership | Unowned non-human identity | Non-human identities with no assigned owner. | +| Ownership | Unowned service account | Service accounts with no assigned owner. | +| Ownership | Deactivated owner | Accounts and resources whose owner has been deactivated. | +| Identity resolution | Similar username match | App accounts that look like they belong to a known identity. | +| Identity resolution | Service account misclassification | Accounts labeled human that behave like service accounts. | +| Credentials | Decoy credential used | A planted [decoy credential](/product/admin/decoys) was used to attempt access. | +| Credentials | Unused secret | Secrets that have gone unused past the inactivity threshold. | +| Credentials | Credential publicly exposed | Credentials found published outside your organization. | +| Credentials | Decoy publicly exposed | A planted [decoy credential](/product/admin/decoys) was found published publicly. | +| Credentials | Expiring credential | ConductorOne's own service principal credentials that are within 30 days of expiring, or have already expired. | +| Configuration | Anomaly detection disabled | Connectors running with sync anomaly detection turned off. | + +## Work with a finding + +Click a finding from the **Overview** or **All findings** tab to open its detail view, which includes: + +- **Evidence** — why C1 flagged this finding, including any confidence score. +- **Activity** — an audit trail of everything that's happened to the finding, including when it was created, when routing rules evaluated against it, and any evidence updates. + +From the detail view, you can take one of the following actions on a finding: + +- **Accept risk** — formally acknowledge the finding as a known risk. Requires a justification and an expiration date. The finding reopens automatically when the acceptance period ends. +- **Suppress** — permanently hide the finding from the default view and exclude it from posture scores. Requires a reason. +- **Snooze** — temporarily hide the finding. Requires a duration (1, 7, 30, or 90 days, or a custom date) and a reason. The finding automatically returns to open status when the snooze period ends. +- **Remediate** — resolve and close the finding. This action only appears for finding types that support it. Its label also varies by finding type — for example, a service account misclassification finding offers **Confirm human** and **Mark as service** instead of a generic remediate button. + +### Act on multiple findings at once + +From **All findings**, select multiple findings with the checkbox column, or use **Select all N in filter** to apply an action to every finding matching your current filters — including filters that couldn't previously be bulk-acted on, like finding type, owner, app resource, and connector. Choose **Snooze**, **Suppress**, **Accept risk**, or **Reopen** from the bulk action menu. + +Because these four actions apply to different finding states, the menu shows how many of your selected findings each one can actually change (for example, "Reopen — 3 of 12"), and the confirmation dialog restates that split before you commit. Only eligible findings are changed. Bulk actions require the same permission as changing a single finding's state, so read-only users don't see the selection controls. + +## Transformation rules + +Transformation rules reshape a finding's data — for example, escalating its severity or adding annotations — before a routing rule acts on it. Use them to make sure the findings that matter most are marked that way consistently. Your routing rules can then act on severity or annotations directly, instead of re-deriving that context from scratch. + +Go to **Findings** > **Transformation rules** to create or manage them. Each rule has: + +- **A match condition** — narrow the rule to a specific app, finding type, or a [CEL expression](/product/admin/expressions) referencing `finding.severity`, `finding.state`, `finding.risk_score`, or `finding.annotations`. Leave everything unset to match every finding. +- **One or more transforms** — set severity, add annotations, or remove annotations. + +For example, to flag every finding on a sensitive app as more urgent, create a rule matching `finding.app_id == ""` that sets severity to Critical. A routing rule can then match on that Critical severity and escalate automatically. + +You can create as many transformation rules as you need. Every rule whose condition matches a finding is applied, in ascending order by the rule's **Order** value — later rules override earlier ones where they conflict. + +## Routing rules + +Routing rules turn triage into automation. Instead of someone opening every finding to decide what happens next, a routing rule matches on a condition and immediately suppresses, snoozes, accepts, remediates, or dispatches it. No manual review is required unless nothing matches. + +Go to **Findings** > **Routing rules** to create or manage them. Each rule has: + +- **A match condition** — the same app, finding type, or CEL expression matching used by transformation rules. +- **An action** — No action, Suppress, Snooze, or Accept risk. Remediate is also available for finding types that support it. +- **Dispatchers (optional)** — fire a webhook, invoke a function, or trigger an automation every time the rule matches. + +For example, suppress low-severity noise automatically with a rule matching `finding.severity == FINDING_SEVERITY_LOW` and action Suppress. Escalate anything Critical with a rule matching `finding.severity == FINDING_SEVERITY_CRITICAL` that triggers an [automation](/product/admin/automations) to notify your team or open a ticket. + +Unlike transformation rules, routing rules stop at the first match. C1 evaluates rules in ascending order by **Order** and applies only the first one that matches. + +### Order rules effectively + +Transformation rules and routing rules order in opposite directions, and mixing up the two is the most common way a rule set stops working as expected. + +- **Transformation rules apply cumulatively** — every matching rule runs, and later rules override earlier ones. Put your general, default-setting rules early and your specific overrides later. +- **Routing rules stop at the first match** — only one rule ever runs. Put your specific, narrow rules early and your general, catch-all rules last. A broad rule placed too early will catch findings a later, more specific rule was meant to handle. + +A few other tips for keeping a rule set maintainable: + +- Test a routing rule's match condition with the **No action** action first, which matches the finding without changing its state. Confirm it's catching the right findings before wiring up Suppress, Snooze, or a dispatcher. +- Leave gaps between **Order** values (10, 20, 30 instead of 1, 2, 3) so you can insert a new rule later without renumbering the rest. +- If you want a default outcome for anything your specific rules don't catch, add a broad rule with no match condition (**Match all**) at the end of your routing rules. + +## Example: catch and escalate decoy credential use + +This walkthrough combines a finding type, a transformation rule, and a routing rule to automatically flag and escalate decoy credential use. It's a strong signal of compromise that shouldn't wait for someone to notice it in the findings list. See [Decoys](/product/admin/decoys) for how to plant a decoy credential. + + + +In **Findings settings**, under **Credentials**, turn on **Decoy credential used**. + + +Save your changes. + + +Go to **Transformation rules** > **Create rule**. + + +Set **Finding type** to **Decoy credential used**, and leave **App** and the expression unset to match every app. + + +Add a **Set severity** transform and set it to **Critical**. + + +Save the transformation rule. + + +Go to **Routing rules** > **Create rule**. + + +Set **Finding type** to **Decoy credential used**. + + +Set **Action** to **No action**, so the finding stays open for review. + + +Add a **Trigger automation** dispatcher to notify your security team immediately. + + +Set this rule's **Order** so it runs before any broad catch-all routing rules. A general rule like "suppress low severity findings" could otherwise match first and prevent this one from running. + + + +From now on, every decoy credential finding is marked Critical, and your security team is notified the moment it's created. No one has to find it in the findings list first. diff --git a/product/release-notes.mdx b/product/release-notes.mdx index e818328a..3e717add 100644 --- a/product/release-notes.mdx +++ b/product/release-notes.mdx @@ -6,7 +6,21 @@ description: Here are the latest new features, enhancements, and resolved issues rss: true sidebarTitle: Release notes --- -{/* Editor Refresh: 2026-08-07 */} +{/* Editor Refresh: 2026-08-13 */} + + + +### Early access: Findings and Decoys + +Catching an unowned service account, an exposed credential, or a misclassified identity has usually meant someone remembering to go looking for it. Findings does the looking for you. Turn on the conditions you care about, and C1 checks for them on every connector sync. From there, transformation and routing rules let you triage, escalate, or resolve what it finds automatically instead of reviewing every finding by hand. + +Stolen credentials usually only surface after they've already been used for real damage. Decoys get ahead of that. Plant a tripwire credential that looks real but grants no access — any attempt to use it raises a Critical finding. Whoever's using it just sees an ordinary authentication failure, with nothing to tell them they tripped a wire. + +Findings also show up on the Identities & NHI dashboard — every inventory table can filter to just the identities with open findings. + +See [Findings](/product/admin/findings) and [Decoys](/product/admin/decoys) for details. Share feedback with the C1 Support team. + +