Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
DESCOPE_PROJECT_ID="YOUR_PROJECT_ID"
DESCOPE_MANAGEMENT_KEY="YOUR_MANAGEMENT_KEY"
DESCOPE_MANAGEMENT_KEY="YOUR_MANAGEMENT_KEY"
DESCOPE_AUTH_MANAGEMENT_KEY="YOUR_AUTH_MANAGEMENT_KEY"
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ You'll need to set up a `.env` file in the root directory with your Descope Proj
```
DESCOPE_PROJECT_ID=<Descope Project ID>
DESCOPE_MANAGEMENT_KEY=<Descope Management Key>
# Optional, only needed for authentication methods with disabled public access
DESCOPE_AUTH_MANAGEMENT_KEY=<Descope Auth Management Key>
```

## Using the SDK
Expand All @@ -38,11 +40,31 @@ use Descope\SDK\DescopeSDK;
$descopeSDK = new DescopeSDK([
'projectId' => $_ENV['DESCOPE_PROJECT_ID'],
'managementKey' => $_ENV['DESCOPE_MANAGEMENT_KEY'], // Optional, only used for Management functions
'authManagementKey' => $_ENV['DESCOPE_AUTH_MANAGEMENT_KEY'], // Optional, only needed for authentication methods with disabled public access
'debug' => false, // Optional, enables verbose error logging (default: false)
'requestTimeout' => 60, // Optional, HTTP request timeout in seconds (default: 60)
]);
```

### Auth Management Key

Authentication methods whose public access has been disabled can still be used by providing an
auth management key. When set, it is sent along with every authentication request.

Create one in the [Descope Console](https://app.descope.com/settings/company/managementkeys) with
either the `Authentication` or `Full Access` scope on the project or company.

```php
$descopeSDK = new DescopeSDK([
'projectId' => $_ENV['DESCOPE_PROJECT_ID'],
'authManagementKey' => $_ENV['DESCOPE_AUTH_MANAGEMENT_KEY'],
]);
```

**Note**: the auth management key can, and probably should, be a different management key than the
one provided as `managementKey` for management API usage. The auth management key is never sent on
management requests, and the management key is never sent on authentication requests.

### HTTP Timeouts

Every HTTP call the SDK makes is bounded so a slow or unresponsive network peer
Expand Down Expand Up @@ -322,6 +344,10 @@ print_r($response);

### User Management Functions

All management functions require a `managementKey`. That key is used only for management functions -
to reach authentication methods whose public access has been disabled, use the
[Auth Management Key](#auth-management-key) instead.

Each of these functions have code examples on how to use them.

> Some of these values may be incorrect for your environment, they exist purely as an example for your own implementation.
Expand Down
1 change: 1 addition & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<file>src/tests/SDKConfigCacheTest.php</file>
<file>src/tests/APIExceptionMappingTest.php</file>
<file>src/tests/APIRetryTest.php</file>
<file>src/tests/APIAuthManagementKeyTest.php</file>
<file>src/tests/APIHttpTimeoutTest.php</file>
<file>src/tests/StaticStateIsolationTest.php</file>
<file>src/tests/EndpointsTest.php</file>
Expand Down
55 changes: 25 additions & 30 deletions src/SDK/API.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class API
private $httpClient;
private $projectId;
private $managementKey;
private $authManagementKey;
private $baseUrl;
private $debug;

Expand All @@ -43,14 +44,18 @@ class API
* @param float|null $requestTimeout Overall request timeout in seconds. Defaults to 60.
* @param ClientInterface|null $httpClient Optional pre-configured Guzzle client. When supplied its own
* transport options (including timeouts) are respected as-is.
* @param string|null $authManagementKey Management key sent with every authentication request so that
* methods whose public access has been disabled can still be used.
* Never sent on management requests.
*/
public function __construct(
string $projectId,
?string $managementKey,
?bool $debug = null,
?string $baseUrl = null,
?float $requestTimeout = null,
?ClientInterface $httpClient = null
?ClientInterface $httpClient = null,
?string $authManagementKey = null
) {
$clientOptions = [
'timeout' => $requestTimeout ?? self::DEFAULT_REQUEST_TIMEOUT_SECONDS,
Expand All @@ -77,6 +82,7 @@ public function __construct(

$this->projectId = $projectId;
$this->managementKey = $managementKey ?? '';
$this->authManagementKey = $authManagementKey ?? '';
$this->baseUrl = EndpointsV1::resolveBaseUrl($projectId, $baseUrl);

// Set debug flag from parameter, environment variable, or default to false
Expand Down Expand Up @@ -128,13 +134,7 @@ private function transformEmptyArraysToObjects($data)
*/
public function doPost(string $uri, array $body, ?bool $useManagementKey = false, ?string $refreshToken = null): array
{
$authToken = "";

if ($refreshToken) {
$authToken = $this->getAuthToken(false, $refreshToken);
} else {
$authToken = $this->getAuthToken($useManagementKey, '');
}
$authToken = $this->getAuthToken($useManagementKey, $refreshToken);

$uri = $this->resolveRequestUrl($uri);

Expand Down Expand Up @@ -179,13 +179,7 @@ public function doPost(string $uri, array $body, ?bool $useManagementKey = false
*/
public function doPatch(string $uri, array $body, ?bool $useManagementKey = false, ?string $refreshToken = null): array
{
$authToken = "";

if ($refreshToken) {
$authToken = $this->getAuthToken(false, $refreshToken);
} else {
$authToken = $this->getAuthToken($useManagementKey, '');
}
$authToken = $this->getAuthToken($useManagementKey, $refreshToken);

$uri = $this->resolveRequestUrl($uri);

Expand Down Expand Up @@ -229,13 +223,7 @@ public function doPatch(string $uri, array $body, ?bool $useManagementKey = fals
*/
public function doGet(string $uri, bool $useManagementKey, ?string $refreshToken = null): array
{
$authToken = "";

if ($refreshToken) {
$authToken = $this->getAuthToken(false, $refreshToken);
} else {
$authToken = $this->getAuthToken($useManagementKey);
}
$authToken = $this->getAuthToken($useManagementKey, $refreshToken);

$uri = $this->resolveRequestUrl($uri);

Expand Down Expand Up @@ -446,22 +434,29 @@ private function getHeaders(string $authToken): array
}

/**
* Constructs the auth token based on whether the management key is used.
* Constructs the auth token: the project ID, then the token the caller presented if there is
* one, then the key for the kind of request being made - the management key for management
* requests, the auth management key for authentication requests. The two keys are never sent
* together.
*
* @param bool $useManagementKey Whether to use the management key for authentication.
* @param bool|null $useManagementKey Whether this is a management request.
* @param string|null $refreshToken Refresh token or access key presented by the caller.
* @return string The constructed auth token.
*/
private function getAuthToken(bool $useManagementKey, ?string $refreshToken = null): string
private function getAuthToken(?bool $useManagementKey, ?string $refreshToken = null): string
{
if ($useManagementKey && !empty($this->managementKey)) {
return $this->projectId . ':' . $this->managementKey;
$parts = [$this->projectId];

if (!empty($refreshToken)) {
$parts[] = $refreshToken;
}

if ($refreshToken) {
return $this->projectId . ':' . $refreshToken;
$key = $useManagementKey ? $this->managementKey : $this->authManagementKey;
if (!empty($key)) {
$parts[] = $key;
}

return $this->projectId;
return implode(':', $parts);
}

/**
Expand Down
3 changes: 2 additions & 1 deletion src/SDK/DescopeSDK.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ public function __construct(array $config)
$debug,
$config['baseUrl'] ?? null,
$requestTimeout,
$httpClient
$httpClient,
$config['authManagementKey'] ?? ''
);
// If OPTIONAL management key was provided in $config
if (!empty($config['managementKey'])) {
Expand Down
Loading