> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trychert.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Security

> Trust boundary, HMAC signature format, sharing posture, and data handling.

How the package authenticates, authorizes, and contains data.

<img src="https://mintcdn.com/cherttechnologiesinc/7NuyCzLl8sIsJEKo/salesforce/diagrams/trust-boundary.svg?fit=max&auto=format&n=7NuyCzLl8sIsJEKo&q=85&s=444c951f50008c46335ab324b6f8c11b" alt="Trust boundary" width="880" height="360" data-path="salesforce/diagrams/trust-boundary.svg" />

## Trust Boundary

| Side of the boundary | What lives there                                                                                                                                                            |
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Inside the Org       | All Apex classes, Custom Metadata, Permission Sets, Lightning Web Components, custom objects, and the signing secret.                                                       |
| On the wire          | One HTTPS request per send, signed with HMAC-SHA256. Payload is JSON; transport is TLS 1.2+.                                                                                |
| Outside the Org      | The Chert messaging service at `console.trychert.com`. Receives signed requests, dispatches to delivery infrastructure, surfaces replies through the inbound REST resource. |

The signing secret never leaves the Org. Apex computes the HMAC over
the request body and sends the signature in a header; the secret bytes
themselves are never transmitted.

## Authentication

### Outbound (Org → Chert)

Every outbound request carries:

```
x-chert-signature: v1,<unix-ts>,<hex>
```

Where:

* `<unix-ts>` is the seconds-since-epoch at which the request was signed.
* `<hex>` is `HMAC-SHA256(<unix-ts>.<raw-body>, signing_secret)` rendered as lowercase hex.

The Chert API rejects requests where:

* `<unix-ts>` is more than 5 minutes in the past (replay window).
* `<unix-ts>` is more than 5 minutes in the future (clock-skew tolerance).
* The HMAC does not match.

### Inbound (Chert → Org)

Reply notifications POST to the `ChertInboundRest` REST resource on the
Org. The resource requires:

```
Authorization: Bearer <ingest_token>
```

The `ingest_token` is generated by you, stored in
`Chert_Tenant__mdt.Ingest_Token__c`, and shared with Chert. It is not
the same value as the outbound signing secret; the two are
independently rotatable.

## Authorization

### Apex Sharing

Every callable Apex class declares its sharing posture explicitly:

| Class                       | Sharing           | Rationale                                                                             |
| --------------------------- | ----------------- | ------------------------------------------------------------------------------------- |
| `ChertSendIMessage`         | `with sharing`    | Runs in the calling user's context. Honours record sharing.                           |
| `ChertBridge`               | `with sharing`    | LWC data layer. Honours record sharing.                                               |
| `ChertEnrichService`        | `with sharing`    | Phone enrichment under the calling user's grants.                                     |
| `ChertEnrichScheduler`      | `with sharing`    | Scheduled job; honours sharing of the scheduled-job owner.                            |
| `ChertEnrichmentRunNowRest` | `with sharing`    | REST resource invoked by authenticated users.                                         |
| `ChertEnrichResultRest`     | `with sharing`    | REST resource for enrichment callbacks; bearer-authenticated.                         |
| `ChertInboundRest`          | `with sharing`    | REST resource for reply ingestion; bearer-authenticated.                              |
| `ChertContactsRest`         | `without sharing` | Site-exposed REST resource gated by bearer token. Documented and bounded — see below. |

`ChertContactsRest` is the only `without sharing` class in the package.
Its scope is read-only on a fixed projection of Contact fields and an
edit on a single mutable field. The bearer-token check runs before any
SOQL or DML, and the field allowlist is enforced server-side. If your
deployment does not need the live-Contacts surface, remove the
Permission Set's class access and disable the Site that exposes it.

### Field-Level Security

The package never bypasses CRUD or FLS. Apex DML on standard objects
runs under the calling user's profile and Permission Set grants. The
Lightning Web Components route every read and write through Apex
classes that honour `WITH USER_MODE` semantics.

### Permission Set Scope

`Chert Messaging User` grants only what end users need:

* Read on the conversation pane's Contact and Lead fields.
* Edit on `Contact.MobilePhone` and the Chert-prefixed enrichment
  fields.
* Read and Create on `Chert_Message__c`. No Edit, no Delete, no View
  All, no Modify All.
* Apex class access for the eight package classes.
* Named Credential access to `Chert_Endpoint`.

The Permission Set does **not** grant `View All Data`, `Modify All
Data`, or any custom user permission.

## Data Handling

### What Crosses the Wire on a Send

| Field                                             | Direction     | Purpose                                                                                |
| ------------------------------------------------- | ------------- | -------------------------------------------------------------------------------------- |
| `tenant_slug`                                     | Out           | Identifies your Org.                                                                   |
| `phone`                                           | Out           | The recipient's E.164 number.                                                          |
| `message`                                         | Out           | The iMessage body.                                                                     |
| `idempotency_key`                                 | Out           | Deterministic dedup key.                                                               |
| `salesforce_record_id`                            | Out           | The Lead, Contact, or Account ID. Used for traceability and inbound reply correlation. |
| `lead.name`, `lead.company`, `lead.custom_fields` | Out, optional | Used to personalize the message body server-side. Pass only if you opt in.             |

### What Crosses on an Inbound Reply

| Field                  | Direction | Purpose                                                            |
| ---------------------- | --------- | ------------------------------------------------------------------ |
| `phone`                | In        | The sender's number.                                               |
| `message`              | In        | The reply body.                                                    |
| `received_at`          | In        | Carrier-side timestamp.                                            |
| `salesforce_record_id` | In        | Correlated to the Salesforce parent record from the original send. |

### Retention

Chert retains conversation data for the duration of the customer
contract plus 30 days for operational continuity, after which it is
purged. Data residency and retention overrides are negotiated through
the Chert master service agreement.

### Sub-Processors

The Chert messaging service depends on a small set of named
sub-processors for delivery, hosting, and observability. The current
list is published at `console.trychert.com/legal/sub-processors` and
is the authoritative source.

## Cryptography

| Property            | Value                                                                                                                                            |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| Signature algorithm | HMAC-SHA256                                                                                                                                      |
| Signature input     | `<unix-ts>.<raw-body>`                                                                                                                           |
| Signature encoding  | Lowercase hex                                                                                                                                    |
| Replay window       | 5 minutes                                                                                                                                        |
| Transport           | TLS 1.2+ enforced by Chert                                                                                                                       |
| Secret rotation     | Rotate the Custom Metadata field; the next signed request uses the new secret. Coordinate with Chert support to overlap windows during rotation. |

## Vulnerability Disclosure

Report security issues to `contact@trychert.com`. Chert's disclosure
policy is 90 days from acknowledgement to public publication.

## Deployment Topology — Hardening Roadmap

The current reference topology exposes the live-Contacts read surface
(`ChertContactsRest`) through a public Salesforce Site, gated by the
bearer ingest token. This is appropriate for Org-internal pilots where
the bearer token is the authentication boundary and the field
projection is intentionally narrow (no `Account` lookup, no Email,
write access scoped to `MobilePhone` only).

The recommended path for production-scale customer deployments is:

1. Replace the public Site with a Connected App configured for the
   **OAuth 2.0 Client Credentials Flow**. Chert obtains an access
   token per request rather than presenting a static bearer.
2. Revoke the Site Guest User's access to `ChertContactsRest`.
3. Rotate the bearer ingest token to invalidate any cached value.

This roadmap is tracked separately and does not block package
installation or pilot use.

## See Also

* [ARCHITECTURE](ARCHITECTURE.md) for the call-graph and async behavior.
* [LIMITS AND CONSIDERATIONS](LIMITS_AND_CONSIDERATIONS.md) for governor-limit math and Shield Platform Encryption support.
* [Salesforce Well-Architected — Trusted / Secure](https://architect.salesforce.com/well-architected/trusted/secure)
