RCS UP3.0 rich deep-link guardrails
A GSMA Universal Profile 3.0 rich deep-link is an RCS suggestion chip (rich_link_action) whose deep_link opens in-app on a UP3.0 handset and
whose fallback_url carries every other recipient to a browser. Before Orbit
dispatches a send that carries one of those URLs — or requests any of the
other UP3.0 surfaces (MLS end-to-end encryption, the UP3.0 profile itself) —
the composed request passes one guardrail evaluation that returns a single
verdict: allow, review, or block.
Why the default posture is safe-by-default
UP3.0’s richer surfaces widen both the attack surface and the recipient experience: a rich deep-link hands the recipient a clickable in-app action, and MLS end-to-end encryption puts message content beyond platform inspection. Orbit’s stance is that a tenant adopts those surfaces deliberately, one capability at a time:- The UP3.0 profile, MLS E2EE, and E2EE acknowledgment flags all default off. A send requesting a capability the tenant never enabled is denied before dispatch — you cannot ship UP3.0 traffic by accident.
- Outbound URL reputation gates delivery: rich deep-link and fallback URLs are scored before send, and a malicious verdict blocks unless you explicitly allowlist the host. That is anti-smishing protection of the shared sender reputation — the one platform-side gate on this page besides STOP carry-over.
- Everything tenant-configurable stays default-open in the fail-open
sense: quiet-hours with no configured window never holds a send, a
malformed window decodes to “open,” and a capability the recipient does
not support degrades to the chip’s
fallback_urlrather than failing.
The guardrail verdict
The send path composes every gate into one verdict object:
The reason codes, quoted from the evaluator:
Consent parity. STOP carries over cross-channel but never invents a new
gating regime: an explicit recipient opt-out recorded on RCS or any parity
channel suppresses the UP3.0 send exactly as it suppresses a plain RCS send.
The verdict does not widen the opt-out — it refuses to let a richer channel
bypass an existing one.
Quiet-hours decode. The window is
<startHour, endHour> in whole hours
[0, 24), recipient-local, and may wrap past midnight (21 → 8 holds 21:00
through 07:59). An empty window (start === end) or an out-of-range bound
decodes to open — a malformed config fails open rather than silently
gating every send. A valid hour that lands inside the window produces a
warn hold only; it never blocks.
Tenant operator guide
Enable a capability. The three rollout flags — UP3.0, MLS E2EE, and the E2EE content-scan acknowledgment — are per-tenant and default off. Enable UP3.0 first; an MLS send without the UP3.0 flag fails on both gates. Do not requestmls_e2ee on a send until the blind-spot acknowledgment is recorded: true
end-to-end encryption removes platform-side CSAM and media-threat scanning on
that channel, and the platform holds every encrypted send until you own that.
That acknowledgment is the conditioning that makes E2EE shippable — the
platform will not encrypt-blind a channel you have not signed off.
Check the recipient first. UP3.0 support is negotiated per recipient and
per bot — a bot that renders rich deep-links to one MSISDN may be talking
UP 2.x to the next. Run the capability check (endpoint surface below) before
a campaign and read universalProfileVersion and featureFlags:
featureFlags.richLinkSupported— the recipient rendersrich_link_actionas a real deep-link. Whenfalse, the recipient opensfallback_urlinstead, which is why both URLs are required on the chip.universalProfileVersion: "3.0"— the floor for rich deep-links and MLS. A recipient negotiating 2.x cannot render the chip; plan around it.- Positive verdicts cache for 24 hours, so a pre-send sweep across a segment is cheap.
RCS_NOT_SUPPORTED and your org-level cross-channel fallback chain advances
(typically RCS → SMS). A recipient that supports RCS but only renders the
fallback_url is not an error path — that is the chip’s designed degradation
on non-UP3.0 handsets.
Curate the deep-link allowlist. Hosts you own can be exempted from
reputation gating: an entry matches the exact host or any subdomain
(e.g. acme.example admits acme.example and t.acme.example). Use it for
your own domains only — allowlisting a third-party shortener removes the
smishing screen for every recipient.
Endpoint surface
All sends and capability checks are rooted athttps://api.orbit.devotel.io/api/v1.
The deep-link itself is a suggestion-chip action on the send payload:
deep_link (UP3.0 handset target) and fallback_url (every other recipient)
are both required HTTPS URLs; app_link and tracking_params are optional
metadata carried through to the rendered action. Both URLs — plus the
fallback — are what the reputation scan scores before send. The full chip
contract (mutual exclusion with open_url, chip limits, carousel placement)
is on the RCS channel page.
Worked example: blocked, re-issued, proven
1. The dirty send gets blocked. You send a campaign chip whosefallback_url points at a third-party link shortener the reputation feed
already lists. The guardrail returns:
{ "decision": "allow", "reasons": [] } and
the message dispatches. If the host had merely scanned suspicious, the send
would hold for review (decision: "review") rather than dispatch or block —
a quarantine you can release once you have verified the destination.
3. Red-team it: the host you allowlisted. Your allowlist contains
acme.example. A red-team test sends a chip whose deep_link is
https://acme.example.evil.example/phish — a host that ends with your
domain string but is not a sub-domain of it. The match is exact-host or
host.endsWith("." + entry), so acme.example.evil.example is not
allowlisted, its malicious score stands, and the send is blocked. That is the
safe default catching the look-alike.
Audit trail
Every verdict leaves a record you can read back:- The
reasons[]codes (deep_link_malicious,rollout_up3_disabled,recipient_opted_out,e2ee_scan_ack_required,quiet_hours,content_scan_blind) are machine-readable and stamped on the message audit trail, so a blocked or held send explains itself post-hoc. - The
flags.contentScanBlindmarker travels with any allowed E2EE send — the audit record preserves that the platform was blind to the payload, so a later review cannot mistake “no scan finding” for “scanned clean.” - Blocked sends surface on the message status and in the delivery log; a
capability-check short-circuit reads back as
RCS_NOT_SUPPORTED, and a reputation block reads back with the verdict reasons. - The URL reputation findings behind a
deep_link_*verdict are the same signals carried on SMS/compose scanning — one scanner, one audit shape, across channels.
Related references
- RCS channel — chip contract, capability check, and the fallback chain.
- RCS onboarding guide — brand → agent → verify → launch.
- Send Gates — quiet hours, DNC, RND, and the other send-time gates.
- Consent Management — the consent records STOP parity reads.
- Opt-Out & Suppression Lists — the suppression layer the recipient-opt-out gate honours.