Skip to content
SDKs · ServerIn developmentView source

PHP

PHP 8.1+, on ext-curl and ext-openssl. No Guzzle.

In development

This SDK is implemented but not yet published to its package registry. Until it ships, collect an opaque evidence blob on the device and appraise it server-side with @rootherald/node (or any available server SDK). The API shown below is the planned surface and may change before release.

terminalbash
composer require rootherald/rootherald

The calls

  • new Rootherald\Client(secretKey: …, baseUrl: …)
  • issueChallenge(ask: [Client::ASK_IDENTITY, …], policy: …, keyPurpose: …)Challenge with ->challengeId, ->challenge.
  • verify($evidence, $challengeId, policy: …)AttestResult: ->verdict (Verdict::ALLOW | WARN | DENY), ->verdictData, ->enrollmentRequired, ->assuranceClaimsMet, key(), device().
  • relayEnroll($blob, $challengeId) / relayActivate($activation).
  • KeySignatures::verify($jwk, $message, $signature): bool — raw or DER.
  • Exceptions in Rootherald\Exceptions: InvalidSecretKeyException, ChallengeException, InvalidEvidenceException, UnknownPolicyException, PolicyDowngradeException, AdmissionRefusedException, QuotaExceededException.

Example

attest.phpphp
use Rootherald\Client;
use Rootherald\Verdict;
use Rootherald\Exceptions\QuotaExceededException;

$rh = new Client(secretKey: getenv('RH_SECRET_KEY'));

// POST /api/challenge
$challenge = $rh->issueChallenge(
    ask: [Client::ASK_IDENTITY, Client::ASK_POSTURE],
    policy: 'rootherald:builtin:strict-hardware',
);
echo json_encode(['challengeId' => $challenge->challengeId, 'challenge' => $challenge->challenge]);

// POST /api/verify — body: { challengeId, evidence }
$body = json_decode(file_get_contents('php://input'), true);
try {
    $result = $rh->verify($body['evidence'], $body['challengeId']);
} catch (QuotaExceededException) {
    http_response_code(429); exit;
}
if ($result->enrollmentRequired)         { http_response_code(409); exit; }
if ($result->verdict !== Verdict::ALLOW) { http_response_code(403); exit; }

$deviceId = $result->device()['ueid'];
if ($key = $result->key()) { $keys->put($deviceId, $key->jwk); }   // only for a key ask, only on pass
echo json_encode(['deviceId' => $deviceId]);

A Laravel sample is at sdk-php/samples/laravel-demo.