1
0
Fork 0
Library to let a PHP app leverage Sharkk SSO.
Find a file
2026-03-30 16:08:09 -05:00
.gitignore Fix up formatting and files 2026-03-30 16:08:09 -05:00
readme.md Fix up formatting and files 2026-03-30 16:08:09 -05:00
sso.php Fix up formatting and files 2026-03-30 16:08:09 -05:00

SSO Client

Minimal library for authenticating users via the Sharkk SSO server. Drop sso.php into your project and you're done.


1. Register Your App with SSO

Send a POST /admin/services/{name} request to the SSO server:

curl -s -X POST https://sso.sharkk.net/admin/services/myapp \
  -H 'X-Admin-Key: <admin_key>' \
  -H 'Content-Type: application/json' \
  -d '{"origins": ["https://myapp.sharkk.net"]}'

The response contains your secret and api_key — save these securely:

{
  "name": "myapp",
  "secret": "64-char-hex",
  "api_key": "48-char-hex",
  "origins": ["https://myapp.sharkk.net"]
}

First-party apps (on the same domain as SSO) can be marked "first_party": true in the SSO server config to skip the user consent prompt.


2. Installation

Copy sso.php to your project and require it:

require 'sso.php';

$sso = new SSO([
	'sso_url'	  => 'https://sso.sharkk.net',
	'service_name' => 'myapp',
	'secret'	   => 'your-64-char-hex-secret',
	'api_key'	  => 'your-48-char-hex-api-key',
	'callback_url' => 'https://myapp.sharkk.net/_auth/callback',
]);

3. Protecting a Page

Add one line to any page that requires authentication:

$user = $sso->require();
// $user['id'], $user['username'], $user['email'], $user['email_verified']
echo "Hello, " . htmlspecialchars($user['username']);

If the user is not logged in, they are automatically redirected to SSO login and back.


4. Handling the Callback

Create a callback endpoint at the URL you specified in callback_url. This is where SSO redirects after a successful login:

// _auth/callback.php
require 'sso.php';
$sso = new SSO([/* config */]);

try {
	$user = $sso->handleCallback();
	// User is now logged in — redirect to your app's home page
	header('Location: /');
} catch (RuntimeException $e) {
	// Token invalid or expired
	http_response_code(400);
	echo 'Authentication failed: ' . htmlspecialchars($e->getMessage());
}

5. Logging Out

$sso->logout('/');  // redirects to SSO logout, then back to /

This clears the local PHP session and redirects to the SSO logout endpoint, which invalidates the SSO session cookie.


6. Per-User App Data

Store arbitrary key-value data on the user's SSO account, namespaced to your app. This data is stored server-side in the SSO server and is accessible across any of your services that share the same namespace.

Requires: app and SSO server must share a cookie domain (e.g. both on *.sharkk.net).

Write data

$user = $sso->require();
$sso->setData('theme', 'dark');
$sso->setData('preferences', ['notifications' => true, 'language' => 'en']);

Read data

$theme = $sso->getData('theme', 'light');  // 'light' is the default
$prefs = $sso->getData('preferences', []);
$all   = $sso->getAllData();  // returns ['theme' => 'dark', 'preferences' => [...]]

7. Server-to-Server API

Use these when you need user info outside of a browser request (e.g. in a background job or webhook handler):

// Look up any user by their SSO ID
$user = $sso->fetchUser($userId);  // null if not found

// Check if a user has been admin-invalidated (forced logout)
if (!$sso->validateUser($userId)) {
	// User was revoked — deny access
}

8. Full Example

A minimal PHP app with login, home page, and logout:

index.php (home page)

<?php
require 'sso.php';
$sso  = new SSO([/* config */]);
$user = $sso->require();  // redirects to SSO if not logged in

$theme = $sso->getData('theme', 'light');
?>
<!DOCTYPE html>
<html>
<body data-theme="<?= htmlspecialchars($theme) ?>">
  <p>Hello, <?= htmlspecialchars($user['username']) ?></p>
  <a href="/logout.php">Log out</a>
</body>
</html>

_auth/callback.php (SSO callback)

<?php
require '../sso.php';
$sso = new SSO([/* config */]);
try {
	$sso->handleCallback();
	header('Location: /');
} catch (RuntimeException $e) {
	http_response_code(400);
	echo htmlspecialchars($e->getMessage());
}

logout.php

<?php
require 'sso.php';
$sso = new SSO([/* config */]);
$sso->logout('https://myapp.sharkk.net/');

9. Config Reference

Key Required Description
sso_url Yes Base URL of the SSO server (no trailing slash)
service_name Yes Service name registered with SSO
secret Yes 64-char hex HMAC secret (for verifying tokens)
api_key Yes 48-char hex API key (for service-to-server calls)
callback_url Yes Full URL of your _auth/callback endpoint
namespace No K-V data namespace (defaults to service_name)
session_key No PHP $_SESSION key to use (default: _sso)

10. Security Notes

  • Tokens are verified with HMAC-SHA256 and a constant-time comparison — safe against timing attacks.
  • The 5-minute token TTL means intercepted redirect tokens expire quickly.
  • PHP sessions are configured with httponly, secure, and samesite=Lax.
  • setData uses your service API key via PUT /api/users/{id}/data — server-to-server, no browser session required.
  • For high-security actions, call $sso->validateUser($user['id']) to confirm the account has not been admin-revoked since the user last logged in.