Security Domain#
Namespace: Infocyph\\Epicrypt\\Security
Scope#
signed URLs
CSRF token management
password reset tokens
email verification tokens
remember tokens
action tokens
key rotation helper
key-ring metadata for rotation windows and purpose-scoped key usage
Signed URLs#
use Infocyph\Epicrypt\Security\SignedUrl;
use Infocyph\Epicrypt\Security\SignedUrlOptions;
$signed = new SignedUrl('url-secret');
$options = new SignedUrlOptions(
method: 'GET',
bindHost: true,
bindScheme: true,
allowArrayParameters: false,
allowedHosts: ['example.com'],
);
$url = $signed->generate('https://example.com/download', ['file' => 'report.csv'], time() + 300, $options);
$isValid = $signed->verify($url);
$result = $signed->verifyResult($url, $options);
verifyResult() exposes verified, expired, invalidSignature, expiresAt and version.
CSRF#
use Infocyph\Epicrypt\Security\CsrfTokenManager;
$csrf = new CsrfTokenManager('csrf-secret', 3600);
$token = $csrf->issueToken('session-id');
$isValid = $csrf->verifyToken('session-id', $token);
Purpose-Bound Tokens#
use Infocyph\Epicrypt\Security\PasswordResetToken;
use Infocyph\Epicrypt\Security\EmailVerificationToken;
use Infocyph\Epicrypt\Security\RememberToken;
use Infocyph\Epicrypt\Security\ActionToken;
$reset = new PasswordResetToken('token-secret', 1800);
$resetToken = $reset->issue('user-1');
$resetOk = $reset->verify($resetToken, 'user-1');
$email = new EmailVerificationToken('token-secret', 86400);
$emailToken = $email->issue('user-1', '[email protected]');
$emailOk = $email->verify($emailToken, '[email protected]');
$remember = new RememberToken('token-secret', 1209600);
$rememberToken = $remember->issue('user-1', 'device-1');
$rememberOk = $remember->verify($rememberToken, 'user-1', 'device-1');
$action = new ActionToken('token-secret', 900);
$actionToken = $action->issue('user-1', 'delete-account');
$actionOk = $action->verify($actionToken, 'user-1', 'delete-account');
Key Rotation Helper#
use Infocyph\Epicrypt\Security\KeyRotationHelper;
$keys = [
'k1' => 'previous-key',
'k2' => 'active-key',
];
$rotation = new KeyRotationHelper();
$signature = $rotation->sign('payload', 'k2', $keys);
$isValidWithKid = $rotation->verify('payload', $signature, $keys, 'k2');
$isValidAgainstSet = $rotation->verify('payload', $signature, $keys);
$result = $rotation->verifyResult('payload', $signature, $keys);
verifyResult() returns KeyVerificationResult with verified, matchedKeyId and usedFallbackKey.
KeyRing Metadata#
Use metadata entries when keys have status, validity windows or scope constraints.
use Infocyph\Epicrypt\Security\KeyRing;
$ring = new KeyRing([
'k2026-05' => [
'key' => 'active-key',
'status' => KeyRing::STATUS_ACTIVE,
'not_before' => 1767225600,
'not_after' => 1798761600,
'purpose' => 'jwt-signing',
],
'k2025-12' => [
'key' => 'fallback-key',
'status' => KeyRing::STATUS_FALLBACK,
'purpose' => 'jwt-signing',
],
], 'k2026-05');
$activeKey = $ring->activeKey();
$ordered = $ring->orderedEntries('jwt-signing', time());