PHPackages                             salesrender/plugin-component-access - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. salesrender/plugin-component-access

ActiveLibrary

salesrender/plugin-component-access
===================================

SalesRender plugin for access tools

0.1.24(2y ago)01.1k↓100%2proprietaryPHPPHP &gt;=7.4.0

Since Nov 19Pushed 2mo ago2 watchersCompare

[ Source](https://github.com/SalesRender/plugin-component-access)[ Packagist](https://packagist.org/packages/salesrender/plugin-component-access)[ RSS](/packages/salesrender-plugin-component-access/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (6)Versions (27)Used By (2)

salesrender/plugin-component-access
===================================

[](#salesrenderplugin-component-access)

Security component for the SalesRender plugin ecosystem. Provides JWT-based authentication, RSA public key management, plugin registration (HPT token storage), and token handling for both incoming and outgoing requests between plugins and the SalesRender backend.

Installation
------------

[](#installation)

```
composer require salesrender/plugin-component-access
```

Requirements
------------

[](#requirements)

- **PHP** &gt;= 7.4.0
- **Extensions:** `ext-json`
- **Dependencies:**

PackageVersionPurpose`lcobucci/jwt`3.3.3JWT token parsing, creation, and verification`league/uri`6.7.2URI parsing for issuer validation`salesrender/plugin-component-db`^0.3.5Database model layer (Model, SinglePluginModelInterface)`salesrender/plugin-component-guzzle`^0.3HTTP client for public key fetching and special requests`salesrender/plugin-component-info`^0.1.2Plugin type information for output tokensArchitecture Overview
---------------------

[](#architecture-overview)

This component handles three core security concerns:

1. **Registration** -- storing the HandshakePluginToken (HPT) received during plugin registration
2. **PublicKey** -- fetching and caching the backend RSA public key for JWT verification
3. **Token** -- verifying incoming JWTs (RS512) and creating outgoing JWTs (HS512)

### Authentication Flow

[](#authentication-flow)

```
SR Backend                              Plugin
    |                                     |
    |-- JWT (RS512, contains HPT) ------->|
    |                                     |-- Verify JWT with PublicKey
    |                                     |-- Extract HPT from JWT
    |                                     |-- Store HPT in Registration model
    |                                     |
    ||
    |                                     |-- Verify with PublicKey::verify()
    |                                     |-- Create GraphqlInputToken
    |                                     |-- Process request
    |                                     |-- Create output JWT (HS512 with HPT)
    |parse($request->getParsedBodyParam('registration'));

// Set the plugin reference from token claims
Connector::setReference(new PluginReference(
    $token->getClaim('cid'),
    $token->getClaim('plugin')->alias,
    $token->getClaim('plugin')->id
));

// Delete old registration if exists
if ($old = Registration::find()) {
    $old->delete();
}

// Create and save new registration (verifies JWT internally)
$registration = new Registration($token);
$registration->save();
```

### 2. Protected Middleware -- Verifying Incoming Requests (from [plugin-core](https://github.com/SalesRender/plugin-core) ProtectedMiddleware)

[](#2-protected-middleware----verifying-incoming-requests-from-plugin-core-protectedmiddleware)

Every protected endpoint verifies the incoming JWT via the `X-PLUGIN-TOKEN` header:

```
use SalesRender\Plugin\Components\Access\Registration\Registration;
use SalesRender\Plugin\Components\Access\Token\GraphqlInputToken;
use SalesRender\Plugin\Components\Db\Components\Connector;

// Extract JWT from header
$jwt = $request->getHeader('X-PLUGIN-TOKEN')[0] ?? '';

if (empty($jwt)) {
    throw new HttpException($request, 'X-PLUGIN-TOKEN not found', 401);
}

try {
    // Parse and verify the JWT (RS512 verification happens inside)
    $token = new GraphqlInputToken($jwt);
    GraphqlInputToken::setInstance($token);
} catch (Exception $exception) {
    throw new HttpException($request, $exception->getMessage(), 403);
}

// Set plugin reference for scoped database queries
Connector::setReference($token->getPluginReference());

// Ensure the plugin has been registered
if (Registration::find() === null) {
    throw new HttpException($request, 'Plugin was not registered', 403);
}
```

### 3. Using Output Token for API Requests (from [plugin-macros-example](https://github.com/SalesRender/plugin-macros-example))

[](#3-using-output-token-for-api-requests-from-plugin-macros-example)

After verification, the output token is used to authenticate requests back to the backend:

```
use SalesRender\Plugin\Components\Access\Token\GraphqlInputToken;
use SalesRender\Plugin\Components\ApiClient\ApiClient;

$token = GraphqlInputToken::getInstance();
$client = new ApiClient(
    $token->getBackendUri() . 'companies/stark-industries/CRM',
    (string) $token->getOutputToken()
);
```

### 4. Making Special Requests to Backend (from [plugin-core-logistic](https://github.com/SalesRender/plugin-core-logistic) BatchShippingHandler)

[](#4-making-special-requests-to-backend-from-plugin-core-logistic-batchshippinghandler)

The `makeSpecialRequest` method creates an HS512-signed JWT and sends it to the backend:

```
use SalesRender\Plugin\Components\Access\Registration\Registration;

// Add orders to a shipping batch
Registration::find()->makeSpecialRequest(
    'PATCH',
    $uri,
    [
        'shippingId' => $shippingId,
        'orders' => $orders,
        'lockId' => $this->lockId,
    ],
    60 * 10 // TTL: 10 minutes
);
```

### 5. Creating Special Request Tokens Manually (from [plugin-core-pbx](https://github.com/SalesRender/plugin-core-pbx) CdrSender)

[](#5-creating-special-request-tokens-manually-from-plugin-core-pbx-cdrsender)

When you need to pass the token string to a deferred request dispatcher rather than sending immediately:

```
use SalesRender\Plugin\Components\Access\Registration\Registration;
use SalesRender\Plugin\Components\Db\Components\Connector;
use XAKEPEHOK\Path\Path;

$registration = Registration::find();
$uri = (new Path($registration->getClusterUri()))
    ->down('companies')
    ->down(Connector::getReference()->getCompanyId())
    ->down('CRM/plugin/pbx/cdr');

$ttl = 60 * 60 * 24; // 24 hours
$jwt = $registration->getSpecialRequestToken($this->cdr, $ttl);

// Use the token string in a deferred request
$request = new SpecialRequest(
    'PATCH',
    (string) $uri,
    (string) $jwt,
    time() + $ttl,
    202
);
```

### 6. Integration Plugin -- Sending GraphQL Mutations (from plugin-integration-taplink)

[](#6-integration-plugin----sending-graphql-mutations-from-plugin-integration-taplink)

Using `makeSpecialRequest` to execute GraphQL mutations on the backend:

```
use SalesRender\Plugin\Components\Access\Registration\Registration;
use SalesRender\Plugin\Components\Db\Components\Connector;

$registration = Registration::find();
$reference = Connector::getReference();

$registration->makeSpecialRequest(
    'POST',
    "{$registration->getClusterUri()}/companies/{$reference->getCompanyId()}/CRM/plugin/integration",
    [
        'query' => 'mutation ($input: AddOrderInput!) { orderMutation { addOrder(input: $input) { id } } }',
        'variables' => ['input' => $variables],
    ],
    300 // TTL: 5 minutes
);
```

### 7. Verifying Special Requests (from [plugin-core](https://github.com/SalesRender/plugin-core) SpecialRequestAction)

[](#7-verifying-special-requests-from-plugin-core-specialrequestaction)

Incoming special requests from the backend are verified using `PublicKey::verify()` directly:

```
use Lcobucci\JWT\Parser;
use SalesRender\Plugin\Components\Access\PublicKey\PublicKey;
use SalesRender\Plugin\Components\Access\Registration\Registration;

$token = (new Parser())->parse($request->getParsedBodyParam('request'));
PublicKey::verify($token);
$claims = json_decode(json_encode($token->getClaims()), true);

// Verify registration exists
if (Registration::find() === null) {
    throw new HttpException($request, 'Plugin was not registered', 403);
}
```

### 8. Checking Settings Access (from [plugin-core](https://github.com/SalesRender/plugin-core) SettingsAccessMiddleware)

[](#8-checking-settings-access-from-plugin-core-settingsaccessmiddleware)

Reading claims from the verified token singleton to check permissions:

```
use SalesRender\Plugin\Components\Access\Token\GraphqlInputToken;

$isSettingsAllowed = GraphqlInputToken::getInstance()
    ->getInputToken()
    ->getClaim('settings', false);

if (!$isSettingsAllowed) {
    throw new HttpException($request, 'Access to settings is not allowed', 403);
}
```

### 9. Reading Registration Metadata (from plugin-logistic-sphere)

[](#9-reading-registration-metadata-from-plugin-logistic-sphere)

Accessing the country and currency stored during registration:

```
use SalesRender\Plugin\Components\Access\Registration\Registration;

$currency = Registration::find()->getCurrency(); // e.g., "USD"
```

### 10. Batch Operations -- Using GraphqlInputToken Singleton (from [plugin-core](https://github.com/SalesRender/plugin-core) BatchPrepareAction)

[](#10-batch-operations----using-graphqlinputtoken-singleton-from-plugin-core-batchprepareaction)

The token singleton is shared across the request lifecycle:

```
use SalesRender\Plugin\Components\Access\Token\GraphqlInputToken;
use SalesRender\Plugin\Components\Batch\Batch;

$batch = new Batch(
    GraphqlInputToken::getInstance(),
    new ApiFilterSortPaginate($filters, $sort, 100),
    Translator::getLang(),
    $request->getParam('arguments', [])
);
$batch->save();
```

JWT Claim Structure
-------------------

[](#jwt-claim-structure)

### Incoming JWT from Backend (RS512)

[](#incoming-jwt-from-backend-rs512)

Claim/HeaderDescription`pkey` (header)MD5 hash of the public key used for signing`iss`Issuer -- backend cluster URI (e.g., `https://backend.salesrender.com`)`aud`Audience -- plugin's own URI (`LV_PLUGIN_SELF_URI`)`cid`Company ID`plugin`Object with `alias` and `id` fields`jti`JWT ID (unique identifier)`HPT`HandshakePluginToken (only present in registration tokens)`country`2-character country code (only in registration tokens)`currency`3-character currency code (only in registration tokens)`settings`Boolean flag indicating whether settings access is allowed (in GraphQL tokens)### Outgoing JWT from Plugin (HS512)

[](#outgoing-jwt-from-plugin-hs512)

#### Output Token (GraphqlInputToken::getOutputToken)

[](#output-token-graphqlinputtokengetoutputtoken)

ClaimDescription`jwt`The original input JWT string`plugin`Plugin type from `Info::getInstance()->getType()`#### Special Request Token (Registration::getSpecialRequestToken)

[](#special-request-token-registrationgetspecialrequesttoken)

ClaimDescription`iss`Plugin's own URI (`LV_PLUGIN_SELF_URI`)`aud`Backend cluster URI`cid`Company ID`plugin`Object with `alias` and `id``body`Request payload array`exp`Expiration time (`time() + $ttl`)See Also
--------

[](#see-also)

- [salesrender/plugin-component-db](https://github.com/SalesRender/plugin-component-db) -- Database model layer, `Model`, `SinglePluginModelInterface`
- [salesrender/plugin-component-guzzle](https://github.com/SalesRender/plugin-component-guzzle) -- HTTP client used for public key download and special requests
- [salesrender/plugin-component-info](https://github.com/SalesRender/plugin-component-info) -- Plugin info/type metadata
- [salesrender/plugin-core](https://github.com/SalesRender/plugin-core) -- Core plugin framework with `ProtectedMiddleware`, `RegistrationAction`, `SpecialRequestAction`

###  Health Score

38

—

LowBetter than 84% of packages

Maintenance59

Moderate activity, may be stable

Popularity17

Limited adoption so far

Community15

Small or concentrated contributor base

Maturity53

Maturing project, gaining track record

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~49 days

Recently: every ~24 days

Total

25

Last Release

814d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/6140af7bf37913fbad3d596efa1376ede23a55ac226a15b61857f4e58fc26c22?d=identicon)[SalesRender](/maintainers/SalesRender)

---

Top Contributors

[![IvanKalashnikov](https://avatars.githubusercontent.com/u/6877306?v=4)](https://github.com/IvanKalashnikov "IvanKalashnikov (6 commits)")[![XAKEPEHOK](https://avatars.githubusercontent.com/u/3051649?v=4)](https://github.com/XAKEPEHOK "XAKEPEHOK (4 commits)")[![disami115](https://avatars.githubusercontent.com/u/45440000?v=4)](https://github.com/disami115 "disami115 (3 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/salesrender-plugin-component-access/health.svg)

```
[![Health](https://phpackages.com/badges/salesrender-plugin-component-access/health.svg)](https://phpackages.com/packages/salesrender-plugin-component-access)
```

###  Alternatives

[laravel/framework

The Laravel Framework.

34.6k509.9M16.9k](/packages/laravel-framework)[tymon/jwt-auth

JSON Web Token Authentication for Laravel and Lumen

11.5k49.1M344](/packages/tymon-jwt-auth)[league/oauth2-server

A lightweight and powerful OAuth 2.0 authorization and resource server library with support for all the core specification grants. This library will allow you to secure your API with OAuth and allow your applications users to approve apps that want to access their data from your API.

6.6k136.0M246](/packages/league-oauth2-server)[kreait/firebase-php

Firebase Admin SDK

2.4k39.7M72](/packages/kreait-firebase-php)[craftcms/cms

Craft CMS

3.6k3.6M2.6k](/packages/craftcms-cms)[shopware/platform

The Shopware e-commerce core

3.3k1.5M3](/packages/shopware-platform)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
