Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
* [#437](https://github.com/workos/workos-php/pull/437) fix(generated): regenerate from spec

**Features**
* **[agents](https://workos.com/docs/reference/agents)**:
* Made `AgentBlueprintsCreateRequest.session_settings` optional
* Added model `AgentTokenValidation`
* Added model `AgentBlueprintsTokenValidateTokenRequest`
* **agents_blueprints_tokens**:
* Added endpoint `POST /agents/blueprints/{agent_blueprint_id}/tokens/validate`
2 changes: 1 addition & 1 deletion .last-synced-sha
Original file line number Diff line number Diff line change
@@ -1 +1 @@
d61348070f219d16b6285f205986c2d332bf6e9c
edb560e2be3f54b668ea8d11fa5a060c87ab5087
8 changes: 8 additions & 0 deletions .oagen-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"lib/Resource/AgentBlueprintsCreateRequestSessionSetting.php",
"lib/Resource/AgentBlueprintsTokenMintTokenRequest.php",
"lib/Resource/AgentBlueprintsTokenMintTokenRequestType.php",
"lib/Resource/AgentBlueprintsTokenValidateTokenRequest.php",
"lib/Resource/AgentBlueprintsUpdateRequest.php",
"lib/Resource/AgentBlueprintsUpdateRequestInvocableBy.php",
"lib/Resource/AgentBlueprintsUpdateRequestSessionSetting.php",
Expand Down Expand Up @@ -75,6 +76,7 @@
"lib/Resource/AgentRegistrationRevokedData.php",
"lib/Resource/AgentRegistrationStatus.php",
"lib/Resource/AgentToken.php",
"lib/Resource/AgentTokenValidation.php",
"lib/Resource/ApiKey.php",
"lib/Resource/ApiKeyCreated.php",
"lib/Resource/ApiKeyCreatedData.php",
Expand Down Expand Up @@ -748,6 +750,7 @@
"tests/Fixtures/agent_blueprints_create_request_invocable_by.json",
"tests/Fixtures/agent_blueprints_create_request_session_setting.json",
"tests/Fixtures/agent_blueprints_token_mint_token_request.json",
"tests/Fixtures/agent_blueprints_token_validate_token_request.json",
"tests/Fixtures/agent_blueprints_update_request.json",
"tests/Fixtures/agent_blueprints_update_request_invocable_by.json",
"tests/Fixtures/agent_blueprints_update_request_session_setting.json",
Expand Down Expand Up @@ -788,6 +791,7 @@
"tests/Fixtures/agent_registration_revoked.json",
"tests/Fixtures/agent_registration_revoked_data.json",
"tests/Fixtures/agent_token.json",
"tests/Fixtures/agent_token_validation.json",
"tests/Fixtures/api_key.json",
"tests/Fixtures/api_key_created.json",
"tests/Fixtures/api_key_created_data.json",
Expand Down Expand Up @@ -2371,6 +2375,10 @@
"POST /user_management/waitlists/{id}/entries": {
"sdkMethod": "createWaitlistEntry",
"service": "userManagement"
},
"POST /agents/blueprints/{agent_blueprint_id}/tokens/validate": {
"sdkMethod": "validateBlueprintToken",
"service": "agents"
}
}
}
8 changes: 4 additions & 4 deletions lib/Resource/AgentBlueprintsCreateRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
public function __construct(
/** Human-readable name of the agent blueprint. */
public string $name,
/** Token and session lifetimes for sessions minted from this blueprint. */
public AgentBlueprintsCreateRequestSessionSetting $sessionSettings,
/** Human-readable description of the agent blueprint. */
public ?string $description = null,
/**
Expand All @@ -24,28 +22,30 @@ public function __construct(
public ?array $permissions = null,
/** Who may mint sessions from this blueprint. */
public ?AgentBlueprintsCreateRequestInvocableBy $invocableBy = null,
/** Token and session lifetimes for sessions minted from this blueprint. */
public ?AgentBlueprintsCreateRequestSessionSetting $sessionSettings = null,
) {
}

public static function fromArray(array $data): self
{
return new self(
name: $data['name'],
sessionSettings: AgentBlueprintsCreateRequestSessionSetting::fromArray($data['session_settings']),
description: $data['description'] ?? null,
permissions: $data['permissions'] ?? null,
invocableBy: isset($data['invocable_by']) ? AgentBlueprintsCreateRequestInvocableBy::fromArray($data['invocable_by']) : null,
sessionSettings: isset($data['session_settings']) ? AgentBlueprintsCreateRequestSessionSetting::fromArray($data['session_settings']) : null,
);
}

public function toArray(): array
{
return [
'name' => $this->name,
'session_settings' => $this->sessionSettings->toArray(),
'description' => $this->description,
'permissions' => $this->permissions,
'invocable_by' => $this->invocableBy?->toArray(),
'session_settings' => $this->sessionSettings?->toArray(),
];
}
}
32 changes: 32 additions & 0 deletions lib/Resource/AgentBlueprintsTokenValidateTokenRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

// This file is auto-generated by oagen. Do not edit.

namespace WorkOS\Resource;

readonly class AgentBlueprintsTokenValidateTokenRequest implements \JsonSerializable
{
use JsonSerializableTrait;

public function __construct(
/** The agent access token (a JWT) to validate. */
public string $agentAccessToken,
) {
}

public static function fromArray(array $data): self
{
return new self(
agentAccessToken: $data['agent_access_token'],
);
}

public function toArray(): array
{
return [
'agent_access_token' => $this->agentAccessToken,
];
}
}
63 changes: 63 additions & 0 deletions lib/Resource/AgentTokenValidation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

declare(strict_types=1);

// This file is auto-generated by oagen. Do not edit.

namespace WorkOS\Resource;

readonly class AgentTokenValidation implements \JsonSerializable
{
use JsonSerializableTrait;

public function __construct(
/** Always `true`: an invalid token is reported as an error with a stable code, never as a `200`. */
public bool $valid,
/** The agent instance the token was minted for. */
public string $agentInstanceId,
/** The agent instance session backing the token. */
public string $agentInstanceSessionId,
/** The organization the agent acts within. */
public string $organizationId,
/**
* The effective permission slugs carried by the token.
* @var array<string>
*/
public array $permissions,
/** The caller-supplied context echoed into the token at mint time, or `null` when none was given. */
public ?string $intent,
/** The delegating user carried in the `act.sub` claim of the token, or `null` for autonomous sessions. */
public ?string $actingUserId,
/** When the backing agent instance session expires. */
public string $sessionExpiresAt,
) {
}

public static function fromArray(array $data): self
{
return new self(
valid: $data['valid'] ?? true,
agentInstanceId: $data['agent_instance_id'],
agentInstanceSessionId: $data['agent_instance_session_id'],
organizationId: $data['organization_id'],
permissions: $data['permissions'],
intent: $data['intent'] ?? null,
actingUserId: $data['acting_user_id'] ?? null,
sessionExpiresAt: $data['session_expires_at'],
);
}

public function toArray(): array
{
return [
'valid' => $this->valid,
'agent_instance_id' => $this->agentInstanceId,
'agent_instance_session_id' => $this->agentInstanceSessionId,
'organization_id' => $this->organizationId,
'permissions' => $this->permissions,
'intent' => $this->intent,
'acting_user_id' => $this->actingUserId,
'session_expires_at' => $this->sessionExpiresAt,
];
}
}
31 changes: 29 additions & 2 deletions lib/Service/Agents.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use WorkOS\Resource\AgentInstanceSession;
use WorkOS\Resource\AgentRegistration;
use WorkOS\Resource\AgentToken;
use WorkOS\Resource\AgentTokenValidation;
use WorkOS\Resource\ClaimViewResponse;

class Agents
Expand Down Expand Up @@ -62,16 +63,16 @@ public function listBlueprints(
* @param string|null $description Human-readable description of the agent blueprint.
* @param array<string>|null $permissions Permission slugs forming the ceiling on what sessions minted from this blueprint may do. Each slug must exist in the environment.
* @param \WorkOS\Resource\AgentBlueprintsCreateRequestInvocableBy|null $invocableBy Who may mint sessions from this blueprint.
* @param \WorkOS\Resource\AgentBlueprintsCreateRequestSessionSetting $sessionSettings Token and session lifetimes for sessions minted from this blueprint.
* @param \WorkOS\Resource\AgentBlueprintsCreateRequestSessionSetting|null $sessionSettings Token and session lifetimes for sessions minted from this blueprint.
* @return \WorkOS\Resource\AgentBlueprint
* @throws \WorkOS\Exception\WorkOSException
*/
public function createBlueprint(
string $name,
\WorkOS\Resource\AgentBlueprintsCreateRequestSessionSetting $sessionSettings,
?string $description = null,
?array $permissions = null,
?\WorkOS\Resource\AgentBlueprintsCreateRequestInvocableBy $invocableBy = null,
?\WorkOS\Resource\AgentBlueprintsCreateRequestSessionSetting $sessionSettings = null,
?\WorkOS\RequestOptions $options = null,
Comment on lines 70 to 76

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Session settings change position

When existing consumers call createBlueprint($name, $sessionSettings) positionally, the settings object now binds to the ?string $description parameter, causing a TypeError. Making this parameter optional should preserve its existing positional slot; the corresponding resource constructor has the same compatibility break.

Prompt To Fix With AI
This is a comment left during a code review.
Path: lib/Service/Agents.php
Line: 70-76

Comment:
**Session settings change position**

When existing consumers call `createBlueprint($name, $sessionSettings)` positionally, the settings object now binds to the `?string $description` parameter, causing a `TypeError`. Making this parameter optional should preserve its existing positional slot; the corresponding resource constructor has the same compatibility break.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

): \WorkOS\Resource\AgentBlueprint {
$body = array_filter([
Expand Down Expand Up @@ -208,6 +209,32 @@ public function createBlueprintToken(
return AgentToken::fromArray($response);
}

/**
* Validate an agent token
*
* Validates an agent access token: verifies its signature against the environment, that it was minted under this blueprint, and that the backing session is live (not revoked or expired, and — for delegated sessions — that the delegating user session has not ended). Returns the token claims and session metadata when valid; invalid tokens are reported as errors with stable codes.
* @param string $agentBlueprintId The unique ID of the agent blueprint.
* @param string $agentAccessToken The agent access token (a JWT) to validate.
* @return \WorkOS\Resource\AgentTokenValidation
* @throws \WorkOS\Exception\WorkOSException
*/
public function validateBlueprintToken(
string $agentBlueprintId,
string $agentAccessToken,
?\WorkOS\RequestOptions $options = null,
): \WorkOS\Resource\AgentTokenValidation {
$body = [
'agent_access_token' => $agentAccessToken,
];
$response = $this->client->request(
method: 'POST',
path: 'agents/blueprints/' . rawurlencode($agentBlueprintId) . '/tokens/validate',
body: $body,
options: $options,
);
return AgentTokenValidation::fromArray($response);
}

/**
* Link a claim attempt to an external user
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"agent_access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6..."
}
12 changes: 12 additions & 0 deletions tests/Fixtures/agent_token_validation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"valid": true,
"agent_instance_id": "agent_01EHWNCE74X7JSDV0X3SZ3KJNY",
"agent_instance_session_id": "agent_session_01EHWNCE74X7JSDV0X3SZ3KJNY",
"organization_id": "org_01EHWNCE74X7JSDV0X3SZ3KJNY",
"permissions": [
"crm:read"
],
"intent": "renew-contract-123",
"acting_user_id": "userland_user_01EHWNCE74X7JSDV0X3SZ3KJNY",
"session_expires_at": "2024-01-01T00:00:00.000Z"
}
17 changes: 16 additions & 1 deletion tests/Service/AgentsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public function testCreateBlueprint(): void
{
$fixture = $this->loadFixture('agent_blueprint');
$client = $this->createMockClient([['status' => 200, 'body' => $fixture]]);
$result = $client->agents()->createBlueprint(name: 'test_value', sessionSettings: \WorkOS\Resource\AgentBlueprintsCreateRequestSessionSetting::fromArray($this->loadFixture('agent_blueprints_create_request_session_setting')));
$result = $client->agents()->createBlueprint(name: 'test_value');
$this->assertInstanceOf(\WorkOS\Resource\AgentBlueprint::class, $result);
$this->assertSame($fixture['id'], $result->id);
$this->assertSame($fixture['name'], $result->name);
Expand Down Expand Up @@ -95,6 +95,21 @@ public function testCreateBlueprintToken(): void
$this->assertStringEndsWith('agents/blueprints/test_agent_blueprint_id/tokens', $request->getUri()->getPath());
}

public function testValidateBlueprintToken(): void
{
$fixture = $this->loadFixture('agent_token_validation');
$client = $this->createMockClient([['status' => 200, 'body' => $fixture]]);
$result = $client->agents()->validateBlueprintToken('test_agent_blueprint_id', agentAccessToken: 'test_value');
$this->assertInstanceOf(\WorkOS\Resource\AgentTokenValidation::class, $result);
$this->assertSame($fixture['agent_instance_id'], $result->agentInstanceId);
$this->assertIsArray($result->toArray());
$request = $this->getLastRequest();
$this->assertSame('POST', $request->getMethod());
$this->assertStringEndsWith('agents/blueprints/test_agent_blueprint_id/tokens/validate', $request->getUri()->getPath());
$body = json_decode((string) $request->getBody(), true);
$this->assertSame('test_value', $body['agent_access_token']);
}

public function testUpdateAttempts(): void
{
$fixture = $this->loadFixture('claim_view_response');
Expand Down