YinkoShield

platform

An infrastructure module inside your app. A signed signal in your stack. Your policy, untouched.

YinkoShield runs as an infrastructure module embedded in your application's user-land — not a developer SDK to wire up, but a platform-portable runtime that observes and signs execution at the moment of action. You consume the evidence where it serves you. Your policy stays where it is.

how it ships

One module. Three consumption surfaces. Decoupled policy.

  1. ·01

    Embed the runtime module

    An infrastructure module embedded in your application's user-land. Runs in-process; observes execution; signs evidence with a hardware-bound key. Platform-portable across mobile, POS, SoftPOS, and SST estates.

  2. ·02

    Choose a consumption channel

    HTTP header, OpenTelemetry span, or ISO 8583 DE 48. The Evidence Token's properties are identical regardless of which channel carries it.

  3. ·03

    Apply your own policy

    YinkoShield never decides. Your risk engine, dispute platform, or audit substrate combines the signed signal with business context — conditional, context-aware, written by you.

  4. ·04

    Test at scale with Signal Lab

    A hosted dashboard with scripted scenarios and a CSV bulk replay (~53,000 events across 1,000 simulated devices). Demos the substrate without installing on your infrastructure.

integration channels

The consumption channel is an integration decision, not a trust decision.

The Evidence Token's cryptographic properties are identical regardless of which channel carries it. Choose the one that fits your existing authorization path.

[ integration channels · the channel is an integration decision, not a trust decision ] EVIDENCE TOKEN Minimal ~200 bytes Standard ~300 bytes + threat events SDK only full detail · in-process ·01 HTTP header X-YinkoShield-Evidence custom request header Minimal or Standard token REST authorization paths ·02 OpenTelemetry span attribute alongside existing telemetry Minimal or Standard token no extra integration layer ·03 ISO 8583 DE 48 · BER-TLV ~216 bytes in DE 48 Minimal or Standard token acquirer / scheme paths ·04 SDK API direct getEvidence() · threat events in-process, on the device tokens + full threat detail superset · no transit needed channels 01–03 · same token, same signature, same verifier · channel 04 · the same plus threat events
Channels 01–03 carry the Evidence Token (Minimal or Standard profile) — identical cryptographic semantics across all three. Channel 04 is the SDK API direct path: it surfaces the same tokens in-process, plus the full threat-events stream with detail that the network channels don't carry.

·01 HTTP header

Custom request header. Zero change to the request body. Compatible with any REST authorization API.

X-YinkoShield-Evidence
POST /v1/payments/authorize HTTP/1.1
Content-Type: application/json
X-YinkoShield-Evidence: eyJhbGci
  OiJFUzI1NiIsImtpZCI6Ii4uLiIs
  InR5cCI6IkpXUyJ9...

{ "amount": "4200.00",
  "currency": "ZAR",
  "merchant_id": "..." }

·02 OpenTelemetry

Token and signal data emitted as OTel span attributes alongside existing telemetry. No additional integration layer.

otel span attribute
from opentelemetry import trace

tracer = trace.get_tracer(__name__)
with tracer.start_as_current_span(
    "payment.authorize"
) as span:
    span.set_attribute(
        "execution_evidence",
        token,
    )

·03 ISO 8583

Embedded in DE 48 / DE 124 / DE 125 via 0xF0 BER-TLV envelope. ~216 bytes total in DE 48 for the Minimal Profile.

DE 48 · BER-TLV
F0 81 D4   -- outer TLV  (212 bytes)
  01 01 01 -- version = 0x01
  02 01 01 -- profile = Minimal
  03 81 CC -- JWS token (204 bytes)
    65 79 4A 68 62
    47 63 69 4F 69
    ...

·04 SDK API direct

In-process consumption. The application code calls the SDK directly to retrieve the signed token — no transit channel needed. For custom telemetry, in-process risk engines, or local logging.

sdk · in-process
// Kotlin / Swift / equivalent
val ev = YinkoShield.getEvidence(
  ctx = paymentContext
)

riskEngine.evaluate(ev)
auditLog.record(ev)
customSink.emit(ev)
reference verifiers

Sovereign verification — any party with a public key.

No YinkoShield endpoint required at verification time. The operator stores public keys and validates ES256 signatures — exactly as it would for any standard PKI.

verifier contract · eight steps

  1. ·1

    Parse JWS

    Header.payload.signature; require alg=ES256, kid present. Reject alg=none.

  2. ·2

    Resolve key

    Lookup kid in the operator key store; one re-fetch over mutually-authenticated channel.

  3. ·3

    Verify signature

    ES256 over BASE64URL(header).BASE64URL(payload). Cryptographic failure rejects.

  4. ·4

    Validate claims

    Required fields present; header kid = payload kid; well-formed UUIDs.

  5. ·5

    Enforce freshness

    ts within operator-defined window (recommended ±5 minutes).

  6. ·6

    Replay check

    (did, tctx, event_name, seq) not present in shared atomic dedup store.

  7. ·7

    Sequence regression

    Retry events: seq must exceed every prior seq for the same tctx.

  8. ·8

    Trust level

    Resolved from Evidence Record when fetched; software_layer otherwise. Declared, not inferred.

Cross-language conformance: the same token verifies the same way in every language, or one of them is broken. Read the deep article →

signal model

What the device declares. Not how it observes.

The signal model declares what is observed, not how it is acquired. Implementation details — accessibility-service abuse detection, overlay detection, hooking, debugger attach — stay in the runtime, not in the spec.

Signal What it observes
device.integrity Boot integrity state — re-flashed device fails verification at first transaction.
runtime.environment Execution environment — emulator detected; declared in evidence.
code.integrity Application code signature — repackaged APK surfaces as software_measured.
binding.status Whether signing key is bound to hardware — TEE-backed vs. software-bound, declared.
network.identity SIM and network identity continuity — SIM swap mid-transaction visible in retry.
operating model

Client-only primitive. No vendor backend in the path. Bilateral engagements.

The substrate has the same operational shape regardless of customer: nothing flows back to YinkoShield, the operator owns every key, and adoption is a procurement conversation, not a subscription.

  • ·01

    Operating model

    The runtime ships as a module embedded in the operator's application. The verifier runs in the operator's stack against operator-stored public keys. There is no YinkoShield endpoint in the verification path. There is no licence check at runtime. There is no telemetry the operator did not ask for.

  • ·02

    Where it does not apply

    EEI requires a runtime host — a mobile app, a POS firmware, or a SST service shell — where the Trusted Runtime Primitive can be embedded. USSD-only flows, SMS-only flows, and any channel without an installable runtime are out of scope by construction. For mobile-money operators, the app channel (the wallet app users install) is in scope; the USSD short-code that runs alongside it is not. The two coexist; EEI signs the app side.

  • ·03

    Engagement shape

    Engagements start with a technical briefing — typically 60 minutes with the operator's authorization, fraud, and platform-engineering leads. A scoped evaluation follows, against the operator's own data and their own risk thresholds. Pricing is a flat annual fee for the primitive — by request, scoped to estate. No per-event metering at runtime; no licence beacon; no usage telemetry to YinkoShield.

  • ·04

    What the operator owns

    Keys (operator-registered, never leaving the device's TEE on generation). Verification (the operator runs the verifier; the spec is the contract). Policy (the operator's risk engine combines signed signals with business context). Data (no PII in evidence; the ledger does not leave the device without an operator-initiated request).

For the spec table of contents, the verifier contract, and the standards lineage — read the specification page.