Enterprise エディション
Licensing — 詳細リファレンス
本ページは、NextPDF Enterprise のライセンシングサーフェス — 他のすべての Enterprise 機能を解決するモジュール — の詳細リファレンスです。エンタイトルメント状態モデル(EntitlementEvaluator、EntitlementStatus、EntitlementResult)、強制される機能ゲーティング(FeatureGate、CapabilityCode、CapabilityRegistry)、2 タイマー方式のチャネル強制マシン(ChannelEnforcementPolicy、OnlineCheckScheduler)、および署名付きオンラインクライアント(LicenseClient)を扱います。通常のエンタイトルメント評価にネットワークは不要です。オンラインクライアントは、明示的なアクティベーション、ハートビート、ディアクティベーション、オンライン検証、更新プローブの各操作のために存在します。内部メカニズムの詳細はソースリポジトリの内部ドキュメントに留められており、本マニュアルの対象外です。
提供状況とライセンス
「提供状況とライセンス」という見出しのセクションこの機能は NextPDF Enterprise(nextpdf/enterprise)に同梱され、Enterprise ティアのライセンスエンベロープで有効化されます。そのエンタイトルメントを持たないデプロイメントは、この機能のクラスをロードしません。エディションを比較してライセンスを取得。
Licensing は Enterprise の基盤サーフェスです。他のすべてを解決するサーフェスであるため、Enterprise パッケージが Core パッケージと並べてインストールされると常に存在します。NextPDF Pro には独立したエンタイトルメントサーフェスはありません。状態モデル、強制マシン、オンラインクライアントは nextpdf/enterprise にのみ同梱されます。NextPDF Core(Apache-2.0)にはエンタイトルメントモデルが一切ありません — ライセンスなしの Apache-2.0 の挙動を必要とするホストは、Enterprise パイプラインではなく Core エンジンを直接使用します。
パブリック API サーフェス
「パブリック API サーフェス」という見出しのセクションすべての型は NextPDF\Enterprise\Licensing の下に置かれます。強制マシンは Channel サブ名前空間に、ランタイム合成は Runtime に、署名付きステータス型は Online にあります。
| シンボル | パラメーター | デフォルト挙動 | 戻り値 | スローまたは失敗 | 備考 |
|---|---|---|---|---|---|
EntitlementEvaluator::evaluate() | ?LicenseKey $license, ?DateTimeImmutable $now = null | 検証済みライセンス(または null)を完全なエンタイトルメント判定にマッピング | EntitlementResult | なし | null ライセンスはフェイルクローズの no-license 結果を生成 |
EntitlementEvaluator::evaluateEnforced() | ?LicenseKey $license, EnforcementOutcome $outcome | 事前計算された強制結果をエンタイトルメント結果に変換 | EntitlementResult | なし | 実効エディションは outcome に由来。あらゆる強制ダウングレードは Core に着地 |
EntitlementEvaluator::resolveBrandingMode(), ::resolveBrandingStrategy() | ?LicenseKey $license, ?DateTimeImmutable $now = null | 生成出力のブランディング判定を解決 | BrandingMode / BrandingStrategy | なし | 唯一のブランディング権限。透かしを入れるのは評価チャネルのみ |
EntitlementResult | 読み取り専用値オブジェクト | ステータス、エディション、チャネル、ブランディングモード、ランタイム/更新/サポートのフラグ、および任意の警告を保持 | — | なし | ヘルパー: isFullyActive(), isExpired(), isDowngradedToCore(), shouldApplyEvaluationBranding() |
EntitlementStatus | 文字列バック enum | Active, GracePeriod, DowngradedToCore, EvaluationExpired, NoLicense | — | なし | PerpetualFallback は保持されているが非推奨。6.0 より前のコンシューマーがコンパイルできるようにするためだけに残されている |
FeatureGate::hasCapability() | CapabilityCode $capability | 強制される実効エディションとパック状態に照らして機能をチェック | bool | なし | リゾルバーエラー時は core へフェイルクローズ |
FeatureGate::requireCapability() | CapabilityCode $capability | 何もせず通過するか、構造化されたアップセルコンテキストとともにスロー | void | SpectrumAuthenticationException SPEC-LIC-001(未ライセンス)または SPEC-LIC-002(パック期限切れ) | コンテキストは required_capability, required_pack, current_packs, upgrade_info_url を保持 |
FeatureGate::isFeatureEnabled(), ::requireFeature() | string $feature | レガシーの機能識別子チェック | bool / void | SpectrumAuthenticationException SPEC-AUTH-007(require パス) | レガシー互換。機能チェックを推奨 |
FeatureGate アクセサー | なし | ライセンスのイントロスペクション | 可変 | なし | currentEdition(), isLicenseValid(), isInGracePeriod(), getActivePacks(), trialPolicy() |
CapabilityCode | 文字列バック enum | 正規の機能識別子(core.*, pro.*, enterprise.*, pack.*) | — | なし | isPack(), packName(), minimumEdition(), forEdition() |
CapabilityRegistry | LicenseKey、ルートパターン | ディスパッチ前のルートから機能への解決とパックの検索 | 可変 | なし | registerDefaultRoutes() は文書化されたサービスルートをカバー |
LicenseKey | 読み取り専用値オブジェクト | パース済みで検証済みのライセンスクレーム | — | なし | isExpired(), isInGracePeriod(), isFullyExpired(), hasFeature(), hasCapability(), activePackNames()。maxSlots は契約上のみ |
LicenseValidator::buildVerifiedLicenseKey() | array $data | 検証済みのペイロードから型付き LicenseKey を構築 | LicenseKey | スキーマ違反時に SpectrumAuthenticationException SPEC-AUTH-001 | スキーマ 2.0、1.0、およびレガシーペイロードをサポート |
PackDefinition / PackRegistry | 読み取り専用値オブジェクト | 独立した期限切れと猶予を持つアドオンパック状態 | 可変 | なし | isActive(), isFullyExpired(), activePacks(), activeCapabilities() |
TrialPolicy | bool $enabled, int $maxPagesPerSecond = 2、透かしフィールド | トライアルのスループット上限ポリシー | — | なし | fromLicenseKey(), disabled(), isThrottled()。ブランディング権限は評価器に留まる |
ChannelEnforcementPolicy::enforce() | LicenseKey $license, LocalState $state, int $systemNow, bool $revoked = false | 2 タイマーマシンに加え、失効とトライアルの再ラベル付けを実行 | EnforcementOutcome | なし | 失効はすべてのタイマーとトライアル状態を上書き |
OnlineCheckScheduler::evaluate(), ::recordSuccessfulOnlineCheck() | ライセンス、ローカル状態、タイムスタンプ | 2 タイマー評価。検証済みサーバー時刻からのリース更新 | EnforcementOutcome / LocalState | なし | ONLINE_GRACE_SECONDS はリースを過ぎても 48 時間の生存猶予を付与 |
EnforcementDecision / EnforcementReason / EnforcementOutcome | enum + 読み取り専用値オブジェクト | Active, Grace, DowngradedToCore に加え、正確な理由 | — | なし | 各理由は 1 つの判定へ決定論的にマッピング |
Runtime\EntitlementResolver::currentEntitlement() | なし | インターフェース: ランタイムが提供する強制されたエンタイトルメント | EntitlementResult | 実装定義 | EnforcedEntitlementResolver はキャッシュ、状態、ポリシー、評価器を合成し、Core へフェイルクローズ |
LicenseStateCache::get(), ::getOrThrow() | bool $forceRefresh = false | ゲートを支える検証済みライセンスのキャッシュ | ?LicenseKey | getOrThrow(): SpectrumAuthenticationException SPEC-AUTH-008。不正な配線時に LicenseConfigurationException | invalidate(), isCacheValid() |
LicenseClient::activate(), ::heartbeat(), ::deactivate(), ::verifyOnline() | string $licenseJws, string $deploymentId, ?string $machineFingerprintHash = null, ?string $expectedLicenseId = null, ?string $clientNonce = null | 1 回の署名付きステータス交換。レスポンスはピン留めルートに照らして検証され、送信した nonce にバインドされる | StatusResponse | LicenseClientException(トランスポート、非 200、不正な供給 nonce)。SpectrumAuthenticationException(偽造、改ざん、古い、nonce 不一致、ライセンス不一致、型不一致のレスポンス) | 送信されるのは常にソルト付きフィンガープリントハッシュのみで、生のフィンガープリントは決して送られない |
LicenseClient::checkRenewal() | string $licenseId, string $customerId | 更新の利用可否プローブ。404 は通常の「利用可能なものなし」という回答 | 更新配列(available, download_url, expires_at) | LicenseClientException(到達不能、非 200/404、またはポリシーで拒否された download_url) | 未署名ボディの URL は、外部へ出る前に SSRF スクリーニングされる |
LicenseClient::__construct() | シグネチャフェンスを参照 | 構築時にトランスポート、URL スキーム、ピンセットを検証 | — | LicenseConfigurationException(ポリシー非強制トランスポート、許可されないスキーム、ピンなしの平文 HTTP、不正なピンセット) | getPinSet() はローテーションツール向けにアクティブなピンセットを公開 |
Online\StatusResponse | 読み取り専用値オブジェクト | 検証済みの署名付きステータス | — | なし | isLive() は revoked / expired / released の場合に false。leaseExpiresAt、スロット数、エンタイトルメントのスナップショットを保持 |
LicenseChannelMode / OnlineMode / OnlinePolicy | enum + 読み取り専用値オブジェクト | チャネルおよびオンラインポリシーのクレーム | — | なし | signed_source 対 ioncube。オンラインモード required / optional / disabled(intervalDays と leaseDays を伴う) |
LicenseEdition | 文字列バック enum | Core, Pro, Enterprise | — | なし | satisfies() がティア階層を実装 |
public function __construct(private ?EvaluationBrandingConfig $evaluationBrandingConfig = null)public function evaluate(?LicenseKey $license, ?DateTimeImmutable $now = null): EntitlementResultpublic function evaluateEnforced(?LicenseKey $license, EnforcementOutcome $outcome): EntitlementResultpublic function resolveBrandingMode(?LicenseKey $license, ?DateTimeImmutable $now = null): BrandingModepublic function resolveBrandingStrategy(?LicenseKey $license, ?DateTimeImmutable $now = null): BrandingStrategypublic function __construct(private readonly LicenseStateCache $licenseCache, private readonly EntitlementResolver $entitlementResolver, private readonly string $upgradeInfoUrl = self::DEFAULT_UPGRADE_URL)public function isFeatureEnabled(string $feature): boolpublic function requireFeature(string $feature): voidpublic function currentEdition(): ?stringpublic function isLicenseValid(): boolpublic function isInGracePeriod(): boolpublic function hasCapability(CapabilityCode $capability): boolpublic function requireCapability(CapabilityCode $capability): voidpublic function getActivePacks(): arraypublic function trialPolicy(): TrialPolicypublic function __construct(private readonly ClientInterface $httpClient, private readonly RequestFactoryInterface $requestFactory, private readonly StreamFactoryInterface $streamFactory, private readonly StatusX5cValidator $statusValidator, private readonly string $baseUrl = self::DEFAULT_BASE_URL, #[SensitiveParameter] private readonly ?string $apiKey = null, array $pinnedPublicKeys = [], array $backupPins = [], private readonly OutboundHttpPolicy $policy = new OutboundHttpPolicy(allowedSchemes: ['https'], connectTimeoutSeconds: 10, readTimeoutSeconds: 30, maxResponseBytes: 10_485_760, followRedirects: false, allowPrivateTargets: false, retryAttempts: 0, retryBaseBackoffMs: 250))public function activate(string $licenseJws, string $deploymentId, ?string $machineFingerprintHash = null, ?string $expectedLicenseId = null, ?string $clientNonce = null): StatusResponsepublic function heartbeat(string $licenseJws, string $deploymentId, ?string $machineFingerprintHash = null, ?string $expectedLicenseId = null, ?string $clientNonce = null): StatusResponsepublic function deactivate(string $licenseJws, string $deploymentId, ?string $machineFingerprintHash = null, ?string $expectedLicenseId = null, ?string $clientNonce = null): StatusResponsepublic function verifyOnline(string $licenseJws, string $deploymentId, ?string $machineFingerprintHash = null, ?string $expectedLicenseId = null, ?string $clientNonce = null): StatusResponsepublic function getPinSet(): ?PinSetpublic function checkRenewal(string $licenseId, string $customerId): array挙動コントラクト
「挙動コントラクト」という見出しのセクションエンタイトルメント評価は、それぞれに固定のランタイム上の帰結を持つ、現行 5 状態のいずれかを生成します。
| ステータス | ランタイム | 実効機能 | 更新/サポート | ブランディング |
|---|---|---|---|---|
Active | 許可 | 付与エディション + アクティブパック | あり(有料)/なし(評価版) | なし(有料)/透かし(評価版) |
GracePeriod | 許可 | 付与エディション + アクティブパック | あり | なし(有料) |
DowngradedToCore | 許可 | Core のみ | なし | なし(有料)/透かし(トライアル) |
EvaluationExpired | 制限 | なし | なし | 透かし |
NoLicense | 無効(フェイルクローズ) | なし | なし | 透かし |
- 有料の期限切れがインストール済みのランタイムを無効化することは決してありません。
runtimeAllowedはすべての有料状態で true のままです。猶予ウィンドウを過ぎると、実効エディションは Core にダウングレードされます。Core 機能は無期限に動作し続け、Pro/Enterprise/パックの機能はすべてゲートオフされ、更新とサポートは取り消されます。非推奨のEntitlementStatus::PerpetualFallbackケースは 6.0 より前の期限切れポリシーを指す名称であり、コンパイル互換性のためだけに存在します。 - すべての状態が Core 実行で終わるわけではありません。 猶予は、期限日付きの更新警告とともに完全な付与エディションを維持します。評価版の期限切れはランタイムを制限し、透かしを維持します。no-license 状態は Enterprise パスをフェイルクローズで無効化し、レガシー出力に目に見える透かしを入れるため、有料実行と取り違えられることは決してありません。
- 固定の解決順序。 完全に期限切れのライセンスは、いかなる機能も解決しません。パック機能は、パック自身のアクティブ状態と独立した期限切れに委ねられます。エディション機能は、Enterprise ⊇ Pro ⊇ Core という厳格な階層において、強制される実効エディションに照らして解決されます。ゲーティングのために生の
LicenseKey::$editionが参照されることは決してありません。 - 2 つのタイマー。最も制限的なものが優先されます。 エンタイトルメントタイマー(両チャネル)は、Active、Grace、および猶予後の Core ダウングレードを駆動します。オンライン生存タイマーは、オンラインモードが
requiredのioncubeチャネルにのみ適用されます。リースと 48 時間の生存猶予が有効でなければなりません。リースを過ぎてオフラインになると、プレミアムは Core ティアで一時停止します。後の検証済みオンラインチェックがリースを再確立し、プレミアムが再開します。signed_sourceチャネル — およびrequired以外のオンラインモード — には生存タイマーがなく、オフラインおよびエアギャップ対応のままです。 - ロールバック対策は決定論的です。 強制は単調な下限に照らして評価します。実効時刻はシステムクロックと最後の検証済み時刻の最大値であるため、クロックを巻き戻しても余分な時間は付与されません。スキュー許容範囲と残りの猶予を超えるロールバックは、Core ダウングレードを強制します。
- リースは信頼できる時刻でのみ進みます。 成功したオンラインチェックは、ローカルクロックではなく、検証済みの署名付きサーバー時刻を記録します。そのため、ローカルクロックを前方にジャンプさせてもリースを水増しできません。
- ブランディングの権限は 1 つです。 透かしをトリガーするのは評価チャネルのみです。有料ライセンスは、ダウングレードされた状態を含むすべての状態で、ブランディングなしに解決されます。
- トライアルは同じタイマー上のポリシーレイヤーです。 スループットは上限付き(デフォルトは 1 秒あたり 2 ページ)で、評価版の透かしが適用され、期限切れは猶予なしで厳格です。変わるのは報告される理由のみで、判定と実効エディションは有料マシンに従います。
- オンラインコントラクトはエンドツーエンドで署名されます。 各リクエストは CSPRNG のクライアント nonce を保持します。各レスポンスはメディアタイプ
application/nextpdf-status+jwtのコンパクトな EdDSA JWS であり、x5c チェーンを通じてコンパイル時に埋め込まれたピン留めルートへと検証され、送信した nonce、インストール済みのライセンス id、および呼び出されたエンドポイントにバインドされます。レガシーの未署名エンベロープトランスポートは廃止され、信頼パスはちょうど 1 つだけ残ります。構成された SPKI ピンはX-NextPDF-Pinned-Public-Keyヘッダーとして送られ、ピンセットにはバックアップピンを含めなければなりません。 - ランタイムでのシート強制はありません。
maxSlotsは契約上のみ — 通常の運用に、テレメトリや必須のフォンホームはありません。
エッジケースと障害モード
「エッジケースと障害モード」という見出しのセクション- 完全に期限切れのライセンスに対する機能チェックは、パックまたはエディションのロジックが実行される前に、「利用不可」へショートサーキットします。
- ベースライセンスがアクティブな間に、アドオンパックが期限切れになることがあります。その場合、拒否は未ライセンス(
SPEC-LIC-001)ではなくパック期限切れ(SPEC-LIC-002)と読み取られ、現在アクティブなパックを列挙します。 - 存在するが読み取り不能またはパース不能なローカル強制状態ファイルは、改ざんのシグナルです。マシンは
EnforcementReason::CorruptStateとともに Core ダウングレードへフェイルクローズします。正当に存在しないファイルは破損ではなく、通常どおり処理が進みます。 - スキュー許容範囲(デフォルト 120 秒)と残りの猶予を超え、単調な下限を下回るクロックのロールバックは、Core ダウングレードを決定論的に強制します。
- 失効した生存リースは、それ以外の点では Active な
ioncubeライセンスをダウングレードします。エンタイトルメントの期限切れは、リース状態にかかわらずダウングレードします。 evaluate(null)はフェイルクローズです。ランタイムは許可されず、透かしが適用され、警告は価格ページの URL を示します。ライセンスなしの Core の挙動を必要とするホストは、Core エンジンを直接構築しなければなりません。- 期限切れの評価版ライセンスには猶予もフォールバックもありません。ランタイムは制限され、透かしは維持されます。
checkRenewal()は HTTP 404 を通常の「利用可能なものなし」という回答として扱います。それ以外の非 200 はLicenseClientExceptionを送出し、アウトバウンドポリシーに違反するdownload_urlは、メソッドから外部へ出る前にフェイルクローズします。- 偽造、改ざん、古い、nonce 不一致、またはライセンス不一致のステータスレスポンスが
StatusResponseを生成することは決してありません。検証はSpectrumAuthenticationExceptionを送出します。署名済みだがrevoked、expired、またはreleasedのステータスは検証を通過し、ダウングレードのシグナルとして表面化します(isLive()は false)。 - 別の交換のために発行されたステータスレスポンスは拒否されます。検証済みの
response_typeは、呼び出されたエンドポイントと一致しなければなりません。 FeatureGateはリゾルバーエラー時にフェイルクローズします。実効エディションはcoreに劣化し、プレミアム機能は一切付与されません。EnforcedEntitlementResolverはエンドツーエンドでフェイルクローズです。そのチェーン内のいかなる例外も、プレミアムの付与ではなく no-license(Core)結果と PSR-3 エラーログを生成します。
FIPS モードの挙動
「FIPS モードの挙動」という見出しのセクションライセンシングレイヤーは独自の暗号ポリシーを一切追加しません。ライセンスおよびステータスの署名は、ホストの暗号プロバイダーが実行する Ed25519 検証です。FIPS 制約のあるビルドでは、プロバイダーが承認しないアルゴリズムは、暗号境界で明示的なエラーとともに失敗します。黙ってダウングレードするものは一切ありません。これらは NextPDF コードに関する機能上の主張です。NextPDF は検証済みの暗号モジュールではなく、いかなる認証も保有せず、いかなる認証も付与しません。
| 主張 | 標準 | 条項 |
|---|---|---|
| ライセンスファイルとステータスレスポンスはコンパクトシリアライゼーションの JWS であり、フェイルクローズで検証される。 | RFC 7515 | §3.1 |
| ライセンスおよびステータスの署名は Ed25519。 | RFC 8032 | §5.1 |
| 署名付きレスポンス内の x5c チェーンは、コンパイル時に埋め込まれたピン留めトラストアンカーへと遡って検証される。 | RFC 5280 | §6.1 |
| 構成された SPKI ピンセットには、未デプロイの鍵のためのバックアップピンを含めなければならない。 | RFC 7469 | §4.3 |
検証されるクレーム(iss, aud, exp, nbf, iat)は登録済みのクレーム名。 | RFC 7519 | §4.1 |
すべての条項は言い換えであり、規範的テキストは一切複製していません。NextPDF はいかなる認証も主張しません。 サポートは適合性と同義ではなく、適合性は認証と同義ではありません。本モジュールは、機能として引用条項に挙動を整合させます。ライセンスまたはステータスエンベロープの受理は、外部の権威ではなく、NextPDF 自身のピン留めルート検証器によって決定されます。
開発上の注記
「開発上の注記」という見出しのセクションLicenseClientは、ポリシーを強制するトランスポート(正規にはSecurityAwareHttpClient)で構築してください。生の PSR-18 クライアントは構築時に拒否されるため、ライセンストラフィックが SSRF 対策、リダイレクトなし、バイト上限、タイムアウトの各制御なしに送られることは決してありません。- 呼び出し側が供給するクライアント nonce は、少なくとも 16 バイトのエントロピーにデコードされなければなりません。ソースはこの下限を RFC 8555 §6.5 に根拠付けています。その条項は引用コーパスの外にあるため、この下限はここでは製品ソースからのみ記載しています。
- 機能は
FeatureGateを通じてゲートしてください。生のLicenseKey::$editionで分岐してはなりません。ゲートは強制される実効エディションのみを参照し、coreへフェイルクローズします。 - 新しいコードで非推奨の
EntitlementStatus::PerpetualFallbackを switch してはなりません。代わりにisDowngradedToCore()をテストするか、DowngradedToCoreにマッチさせてください。 - 機能の拒否は是正のペイロードとして扱ってください。汎用エラーに潰すのではなく、その構造化されたコンテキストとアップグレード URL を呼び出し側に提示してください。
- 本モジュールは暗号機能に関わります。ご自身のレビューではセキュリティ上重要なものとして扱ってください。キャパシティおよびシートの条件は、ランタイムの強制ではなく、ライセンス契約によって定められます。このリファレンスは法的意見ではありません。お客様自身のコンプライアンスおよび法務の助言者にご相談ください。
公開の境界
「公開の境界」という見出しのセクション本ページは、外部から観測可能な挙動とサポートされるパブリック API サーフェスのみを文書化しています。内部名前空間パス、ヘルパークラス、メカニズムの表、ランブックのファイル名、チケットのプレフィックスは対象外です。
- Licensing — NextPDF Enterprise — セットアップと連携ガイダンスを含む機能ページ。
- Billing — 詳細リファレンス — プランティア、超過ポリシー、繰り越し。
- SaaS — 詳細リファレンス — ルートマップが保護するマルチテナントサービスサーフェス。
- Branding — 詳細リファレンス — 評価器が解決するブランディング戦略。