Enterprise รุ่น
Webhook — เอกสารอ้างอิงเชิงลึก
โดยสังเขป
หัวข้อที่มีชื่อว่า “โดยสังเขป”เนมสเปซ NextPDF\Enterprise\Webhook มาพร้อมการส่ง webhook ที่จำกัดขอบเขตต่อ tenant สำหรับ job event พื้นผิวสาธารณะประกอบด้วยหกสัญลักษณ์ ได้แก่ WebhookManager, WebhookRegistration, WebhookPayload, WebhookDelivery, WebhookRetryPolicy และ DeadLetterEntry ตัวจัดการลงทะเบียน endpoint ต่อ tenant และ dispatch job event ไปยังการลงทะเบียนที่สมัครรับ delivery engine จะ POST JSON payload ที่ลงนามแบบ HMAC-SHA256, ตรวจสอบทุกปลายทางกับเกต egress แบบ SSRF ของ Core, ลองใหม่ด้วย exponential backoff และบันทึกความล้มเหลวถาวรไว้ในคิว dead-letter ในหน่วยความจำ ตั้งแต่ 3.1.0 ลายเซ็นจะผูก header X-NextPDF-Timestamp เข้ากับ base string ของ MAC ผู้รับจึงตรวจสอบความสดใหม่และความครบถ้วนพร้อมกัน สำหรับคู่มือระดับเวิร์กโฟลว์ ดู Webhook
ความพร้อมใช้งานและการให้สิทธิ์
หัวข้อที่มีชื่อว่า “ความพร้อมใช้งานและการให้สิทธิ์”ความสามารถนี้มาในแพ็กเกจ NextPDF Enterprise (nextpdf/enterprise) และเปิดใช้งานด้วย license envelope ระดับ Enterprise การปรับใช้ที่ไม่มีสิทธิ์ดังกล่าวจะไม่โหลดคลาสของความสามารถนี้ เปรียบเทียบรุ่นและขอรับสิทธิ์การใช้งาน
พื้นผิว webhook เป็นความสามารถพื้นฐานของ Enterprise ที่พร้อมใช้งานเมื่อติดตั้งแพ็กเกจ Enterprise แล้ว ไม่มีแฟล็กต่อฟีเจอร์แยกต่างหาก NextPDF Core (Apache-2.0) และ NextPDF Pro ไม่มีพื้นผิวการลงทะเบียนหรือการส่ง webhook ตัวจัดการ การลงทะเบียน payload, delivery engine, นโยบายการลองใหม่ และรายการ dead-letter มาในแพ็กเกจ nextpdf/enterprise เท่านั้น
พื้นผิว API สาธารณะ
หัวข้อที่มีชื่อว่า “พื้นผิว API สาธารณะ”| สัญลักษณ์ | พารามิเตอร์ | พฤติกรรมเริ่มต้น | คืนค่า | โยนหรือล้มเหลวด้วย | หมายเหตุ |
|---|---|---|---|---|---|
WebhookManager::__construct | WebhookDelivery $delivery, ?LoggerInterface $logger = null | สร้างตัวจัดการที่มีดัชนีการลงทะเบียนในหน่วยความจำที่ว่างเปล่า | WebhookManager ใหม่ | ไม่โยนข้อยกเว้น | การลงทะเบียนถูกจัดทำดัชนีต่อ tenant |
WebhookManager::register | TenantContext $tenant, WebhookRegistration $registration | เพิ่มการลงทะเบียนต่อท้ายดัชนีของ tenant ที่เรียกใช้ | void | InvalidArgumentException เมื่อ tenant ของการลงทะเบียนไม่ตรงกับ tenant ของ context | การลงทะเบียนข้าม tenant ถูกปฏิเสธก่อนการจัดเก็บ |
WebhookManager::unregister | TenantContext $tenant, string $registrationId | แทนที่การลงทะเบียนที่ตรงกันด้วยสำเนาที่ปิดใช้งาน | bool | ไม่โยนข้อยกเว้น คืนค่า false เมื่อไม่พบ id | ปิดใช้งานแบบ soft รักษาประวัติไว้ |
WebhookManager::activeRegistrations | TenantContext $tenant | กรองการลงทะเบียนของ tenant ให้เหลือเฉพาะที่ใช้งานอยู่ | list<WebhookRegistration> | ไม่โยนข้อยกเว้น | มองเห็นเฉพาะการลงทะเบียนของ tenant ที่เรียกใช้เท่านั้น |
WebhookManager::dispatch | TenantContext $tenant, JobEvent $event | ส่ง event ไปยังทุกการลงทะเบียนที่ใช้งานอยู่ซึ่งสมัครรับ event type นั้น | int (จำนวนการส่งที่สำเร็จ) | ส่งต่อ JsonException เมื่อ event data ไม่สามารถเข้ารหัสเป็น JSON ได้ ความล้มเหลวของการส่งไม่โยนข้อยกเว้น | สร้าง delivery id แบบ 32-hex ใหม่ต่อการส่งของแต่ละการลงทะเบียน |
WebhookRegistration::__construct | string $id, string $tenantId, string $url, array $events, string $secret, bool $active = true, ?string $description = null | จัดเก็บค่าที่ให้มาตามที่เป็น | WebhookRegistration ใหม่ | ไม่มี @throws ที่ประกาศไว้ PHP จะยก TypeError เมื่อชนิดของอาร์กิวเมนต์ไม่ตรงกันภายใต้ strict_types | final readonly $events ที่ว่างเปล่าหมายถึงสมัครรับทั้งหมด |
WebhookRegistration::subscribesTo | JobEventType $eventType | true เมื่อ $events ว่างเปล่าหรือมี type นั้นอยู่ | bool | ไม่โยนข้อยกเว้น | การเปรียบเทียบเอกลักษณ์แบบเข้มงวด |
WebhookRegistration::deactivate | — | คืนสำเนาที่ไม่ใช้งาน | self | ไม่โยนข้อยกเว้น | อินสแตนซ์เดิมไม่เปลี่ยนแปลง |
WebhookPayload::fromJobEvent | JobEvent $event, string $tenantId, string $deliveryId | คัดลอก job id, event type, data และ timestamp จาก event | self | ไม่โยนข้อยกเว้น | static factory ที่ dispatch ใช้ |
WebhookPayload::toJson | — | serialize body หกฟิลด์โดยไม่ escape slash | non-empty-string | JsonException เมื่อ event data ไม่สามารถเข้ารหัสเป็น JSON ได้ | JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES |
WebhookPayload::toArray | — | คืน body เป็น associative array | array<string, mixed> | ไม่โยนข้อยกเว้น | timestamp จัดรูปแบบเป็น RFC 3339 extended |
WebhookPayload::signedTimestamp | — | เวลาของ event เป็นหน่วยวินาที Unix จำกัดค่าให้เป็นศูนย์หรือมากกว่า | int<0, max> | ไม่โยนข้อยกเว้น | ปล่อยออกเป็น X-NextPDF-Timestamp และผูกเข้ากับ MAC |
WebhookPayload::sign | string $secret | HMAC-SHA256 เหนือ base string {signedTimestamp}.{jsonBody} | non-empty-string (hex) | JsonException ผ่าน toJson() เมื่อ body ไม่สามารถเข้ารหัสได้ | ผูก header timestamp เข้ากับ body ด้วยวิธีการเข้ารหัส |
WebhookDelivery::__construct | ClientInterface $httpClient, RequestFactoryInterface $requestFactory, StreamFactoryInterface $streamFactory, WebhookRetryPolicy $retryPolicy = new WebhookRetryPolicy(), ?LoggerInterface $logger = null | delivery engine แบบ PSR-18/PSR-17 ที่มีคิว dead-letter ว่างเปล่า | WebhookDelivery ใหม่ | ไม่โยนข้อยกเว้น | นโยบายเริ่มต้น: 5 ความพยายาม, base 1 s, จำกัด 300 s |
WebhookDelivery::deliver | WebhookRegistration $registration, WebhookPayload $payload | POST payload ที่ลงนามพร้อมการตรวจสอบ egress แบบ SSRF ต่อความพยายามและ exponential backoff | bool | JsonException ก่อนความพยายามครั้งแรกเมื่อ body ไม่สามารถเข้ารหัสได้ มิฉะนั้นจะไม่โยนข้อยกเว้น — false หมายถึง payload ถูกส่งไปยังคิว dead-letter | true เฉพาะเมื่อตอบกลับด้วย 2xx เท่านั้น |
WebhookDelivery::deadLetters | — | คืนรายการที่บันทึกไว้ทั้งหมด | list<DeadLetterEntry> | ไม่โยนข้อยกเว้น | ในหน่วยความจำ จำกัดขอบเขตต่อกระบวนการ |
WebhookDelivery::clearDeadLetters | — | ล้างคิว dead-letter | void | ไม่โยนข้อยกเว้น | ย้อนกลับไม่ได้ ส่งออกรายการก่อนหากต้องการการ replay |
WebhookRetryPolicy::__construct | int $maxRetries = 5, int $baseDelaySeconds = 1, int $maxDelaySeconds = 300 | จัดเก็บค่าของนโยบาย | WebhookRetryPolicy ใหม่ | ไม่มี @throws ที่ประกาศไว้ พารามิเตอร์ระบุเป็น positive-int | $maxRetries นับจำนวนความพยายามทั้งหมด |
WebhookRetryPolicy::delayForAttempt | int $attempt | baseDelaySeconds × 2^(attempt − 1) จำกัดที่ maxDelaySeconds | positive-int | ไม่โยนข้อยกเว้น | หมายเลขความพยายามเริ่มนับจาก 1 |
WebhookRetryPolicy::shouldRetry | int $currentAttempt | true ขณะที่ความพยายามปัจจุบันยังต่ำกว่าค่าสูงสุด | bool | ไม่โยนข้อยกเว้น | การรอจะถูกข้ามหลังจากความพยายามครั้งสุดท้าย |
WebhookRetryPolicy::default | — | 5 ความพยายาม, base 1 s, จำกัด 300 s | self | ไม่โยนข้อยกเว้น | static factory ค่าเริ่มต้นสำหรับการใช้งานจริง |
WebhookRetryPolicy::aggressive | — | 10 ความพยายาม, base 2 s, จำกัด 600 s | self | ไม่โยนข้อยกเว้น | static factory สำหรับ endpoint ที่สำคัญยิ่ง |
DeadLetterEntry::__construct | string $id, string $registrationId, WebhookPayload $payload, int $attempts, string $lastError, ?int $lastHttpStatus, DateTimeImmutable $failedAt, bool $replayed = false | จัดเก็บระเบียนความล้มเหลวตามที่เป็น | DeadLetterEntry ใหม่ | ไม่มี @throws ที่ประกาศไว้ TypeError ภายใต้ strict_types | final readonly $lastHttpStatus ที่เป็น null หมายถึงความล้มเหลวของการขนส่ง |
DeadLetterEntry::markReplayed | — | คืนสำเนาที่มี replayed = true | self | ไม่โยนข้อยกเว้น | id เดิม รายการเดิมไม่เปลี่ยนแปลง |
public function __construct( private readonly WebhookDelivery $delivery, private readonly ?LoggerInterface $logger = null,) {}
public function register(TenantContext $tenant, WebhookRegistration $registration): void
public function unregister(TenantContext $tenant, string $registrationId): bool
public function activeRegistrations(TenantContext $tenant): array
public function dispatch(TenantContext $tenant, JobEvent $event): intpublic function __construct( public string $id, public string $tenantId, public string $url, public array $events, public string $secret, public bool $active = true, public ?string $description = null,) {}
public function subscribesTo(JobEventType $eventType): bool
public function deactivate(): selfpublic static function fromJobEvent( JobEvent $event, string $tenantId, string $deliveryId,): self
public function toJson(): string
public function toArray(): array
public function signedTimestamp(): int
public function sign(string $secret): stringpublic function __construct( private readonly ClientInterface $httpClient, private readonly RequestFactoryInterface $requestFactory, private readonly StreamFactoryInterface $streamFactory, private readonly WebhookRetryPolicy $retryPolicy = new WebhookRetryPolicy(), private readonly ?LoggerInterface $logger = null,) {}
public function deliver(WebhookRegistration $registration, WebhookPayload $payload): bool
public function deadLetters(): array
public function clearDeadLetters(): voidpublic function __construct( public int $maxRetries = 5, public int $baseDelaySeconds = 1, public int $maxDelaySeconds = 300,) {}
public function delayForAttempt(int $attempt): int
public function shouldRetry(int $currentAttempt): bool
public static function default(): self
public static function aggressive(): selfpublic function __construct( public string $id, public string $registrationId, public WebhookPayload $payload, public int $attempts, public string $lastError, public ?int $lastHttpStatus, public DateTimeImmutable $failedAt, public bool $replayed = false,) {}
public function markReplayed(): selfสัญญาพฤติกรรม
หัวข้อที่มีชื่อว่า “สัญญาพฤติกรรม”- การลงทะเบียนถูกจัดทำดัชนีต่อ tenant
register()ปฏิเสธการลงทะเบียนที่ tenant identifier ไม่ตรงกับ context ที่เรียกใช้unregister()เป็นการปิดใช้งานแบบ soft คือการลงทะเบียนถูกแทนที่ด้วยสำเนาที่ไม่ใช้งาน รักษาประวัติไว้ในขณะที่กันออกจากการ dispatch ในอนาคต dispatch()วนซ้ำเฉพาะการลงทะเบียนที่ใช้งานอยู่ของ tenant ที่เรียกใช้ซึ่งสมัครรับ event type ที่ถูก dispatch รายการ subscribed-event ที่ว่างเปล่าหมายถึงสมัครรับทั้งหมด ค่าที่คืนนับจำนวนการส่งที่สำเร็จ- การส่งแต่ละครั้งเป็น HTTP POST ที่มี JSON body และ header ห้าตัว ได้แก่
Content-Type: application/json,X-NextPDF-Signature(sha256=<hex>),X-NextPDF-Timestamp(วินาที Unix),X-NextPDF-Delivery-IdและX-NextPDF-Event - ฟิลด์ใน JSON body ได้แก่
delivery_id,job_id,event_type,data,timestamp(RFC 3339 extended) และtenant_idโดย serialize แบบไม่ escape slash ค่า event-type มาจากJobEventTypeในnextpdf/coreได้แก่progress,completed,failed,cancelled - สคีมาลายเซ็น (เปลี่ยนใน 3.1.0 เป็น breaking) base string ของ HMAC-SHA256 คือ
{signedTimestamp}.{jsonBody}โดยใช้คีย์เป็น registration secret ไม่ใช่ body เพียงอย่างเดียว ค่าX-NextPDF-Timestampเป็นองค์ประกอบ timestamp ของ MAC ดังนั้น header timestamp ที่ถูกดัดแปลงหรือ replay จะทำให้ลายเซ็นใช้ไม่ได้ - การตรวจสอบฝั่งผู้รับ: อ่าน header
X-NextPDF-Timestampเป็นTปฏิเสธเมื่อTอยู่นอกหน้าต่างความสดใหม่ที่ยอมรับได้ (เช่น 300 s) คำนวณhash_hmac('sha256', T . '.' . rawBody, secret)ใหม่เหนือไบต์ดิบที่ได้รับ แล้วเปรียบเทียบในเวลาคงที่กับค่าใน header หลังจากตัดคำนำหน้าsha256=ออก - body, ลายเซ็น และ delivery id ถูกคำนวณเพียงครั้งเดียวต่อการส่งและคงที่ตลอดการลองใหม่
- เกต egress แบบ SSRF ก่อนทุกความพยายาม URL ปลายทางต้องผ่านเกต
UrlValidator::validateExternalUrl()ของ Core คือ อนุญาตเฉพาะสคีม HTTPS เท่านั้น บล็อกช่วง loopback, private, reserved, carrier-grade-NAT, cloud-metadata และช่วง transition ของ IPv6 ที่ฝัง IPv4 hostname จะถูก resolve ผ่าน DNS (A และ AAAA) และ host ที่ resolve ไม่ได้จะถูกปฏิเสธแบบ fail-closed URL ที่ถูกบล็อกจะไม่ถูกส่งเลย ลูปความพยายามจะยกเลิกและ payload จะถูกส่งตรงไปยังคิว dead-letter พร้อมข้อผิดพลาดล่าสุดBlocked SSRF destination:และสถานะ HTTP เป็น null - การจำแนกผลลัพธ์ต่อความพยายาม: 2xx คือสำเร็จและคืนค่าทันที 4xx ที่ไม่ใช่ 429 เป็น terminal และไปยัง dead-letter โดยตรง ผลลัพธ์อื่นทุกแบบ — 3xx, 429, 5xx หรือข้อยกเว้นด้านการขนส่ง — เป็น retryable ได้สูงสุดตามจำนวนความพยายามทั้งหมดของนโยบาย
- backoff เป็นแบบ exponential คือเวลารอก่อนความพยายามถัดไปคือ
baseDelaySeconds × 2^(attempt − 1)จำกัดที่maxDelaySecondsการรอจะถูกข้ามหลังจากความพยายามครั้งสุดท้าย - เมื่อไม่มีความพยายามใดสำเร็จ
DeadLetterEntryจะบันทึก id ที่ไม่ซ้ำ, registration id, payload เดิม, จำนวนความพยายาม (จำกัดที่ค่าสูงสุดของนโยบาย), ข้อความข้อผิดพลาดล่าสุด, สถานะ HTTP ล่าสุด (null เมื่อความล้มเหลวของการขนส่งหรือถูกบล็อกแบบ SSRF) และ timestamp ความล้มเหลว - คิว dead-letter อยู่ในหน่วยความจำและจำกัดขอบเขตต่ออายุของกระบวนการ
markReplayed()สร้างสำเนาที่ติดเครื่องหมาย ไม่ได้ส่งซ้ำ และคิวยังคงเก็บรายการเดิมไว้
กรณีขอบและโหมดความล้มเหลว
หัวข้อที่มีชื่อว่า “กรณีขอบและโหมดความล้มเหลว”- รายการ event ว่างเปล่า การลงทะเบียนจะรับ event type ทุกแบบ กำหนดขอบเขตรายการอย่างชัดเจนเมื่อผู้รับไม่ควรเห็น event ทั้งหมด
- 4xx แบบ terminal เทียบกับความล้มเหลวของการขนส่ง การปฏิเสธด้วย 4xx บันทึก
lastHttpStatusที่มีค่า ส่วนความล้มเหลวของการเชื่อมต่อบันทึกเป็น null ใช้ค่า null เพื่อแยกการปฏิเสธของผู้รับออกจากความล้มเหลวของการขนส่ง - ปลายทางที่ถูกบล็อกแบบ SSRF การลงทะเบียนที่ชี้ไปยังที่อยู่ HTTP, private, loopback หรือ metadata จะเข้าสู่ dead-letter ในความพยายามครั้งแรกพร้อมข้อผิดพลาด
Blocked SSRF destination:และสถานะ null ไม่มีการส่งคำขอออกไป แก้ไข URL แล้วลงทะเบียนใหม่ - ผู้รับรุ่นเก่าหลังการอัปเกรด ผู้รับที่ยังตรวจสอบ HMAC แบบ body-only ก่อน 3.1.0 จะล้มเหลวแบบ fail closed กับการส่งของ 3.1.0 ย้ายผู้รับไปใช้ base string
{timestamp}.{body}และรับค่าX-NextPDF-Timestamp - event data ที่เข้ารหัสไม่ได้
toJson()และsign()โยนJsonExceptionซึ่งส่งต่อออกจากdeliver()และdispatch()ก่อนที่จะมีความพยายามใด ๆ - การบล็อกแบบซิงโครนัส
deliver()หน่วงเวลาแบบ inline ระหว่างความพยายาม backoff สะสมถึง 15 s ภายใต้นโยบาย default และประมาณ 17 นาทีภายใต้นโยบาย aggressive ให้ dispatch จาก queue worker เมื่อ latency ของผู้รับไม่น่าเชื่อถือ - การจำกัดจำนวนความพยายาม จำนวนความพยายามที่บันทึกไม่เกินค่าสูงสุดของนโยบาย แม้ว่าตัวนับลูปภายในจะเลื่อนเกินไปเมื่อความพยายามหมดลง
- การเติบโตและความคงทนของคิว คิว dead-letter เติบโตแบบไม่จำกัดภายในกระบวนการและหายไปเมื่อรีสตาร์ท ส่งออกรายการผ่าน
deadLetters()และเก็บไว้ภายนอกก่อนเรียกclearDeadLetters()เมื่อต้องการการ replay แบบคงทน - การ replay ขับเคลื่อนโดยผู้ดำเนินการ การส่งซ้ำหมายถึงการเรียก
deliver()อีกครั้งด้วย payload ของรายการนั้นmarkReplayed()เพียงบันทึกข้อเท็จจริงลงบนสำเนาเท่านั้น - ความเสี่ยงตกค้างจาก DNS-rebinding URL ถูกตรวจสอบซ้ำในทุกความพยายาม ซึ่งลดแต่ไม่ปิดหน้าต่างของการ rebinding คือ abstraction แบบ PSR-18 ไม่สามารถตรึงการเชื่อมต่อไว้กับ IP ที่ตรวจสอบแล้วได้ เพิ่มการควบคุม egress ในระดับเครือข่ายเมื่อความเสี่ยงตกค้างนี้มีนัยสำคัญ
- การจัดการ secret registration secret เป็นข้อมูลรับรอง HMAC ยืนยันความครบถ้วนและที่มาเท่านั้น — ไม่ใช่ความลับ อย่าใส่ข้อมูลที่ผู้รับไม่ควรเห็นลงใน event payload
พฤติกรรมในโหมด FIPS
หัวข้อที่มีชื่อว่า “พฤติกรรมในโหมด FIPS”การลงนาม payload เป็น HMAC-SHA256 ผ่าน hash_hmac() ของ PHP จึงพึ่งพา crypto provider ของ host ใน build ที่ถูกจำกัดด้วย FIPS ไพรมิทีฟที่ไม่ผ่านการอนุมัติจะล้มเหลวที่ขอบเขตทางการเข้ารหัสแทนที่จะลดระดับลง เลเยอร์ webhook ไม่ได้เพิ่มนโยบายทางการเข้ารหัสของตัวเอง
ความสอดคล้อง
หัวข้อที่มีชื่อว่า “ความสอดคล้อง”- การตรวจสอบสิทธิ์ payload ใช้ HMAC ซึ่งเป็น keyed-hash message authentication code ของ FIPS PUB 198-1 §1 โดยสร้างอินสแตนซ์ด้วย SHA-256
- การป้องกัน replay เป็นไปตามแนวทางความปลอดภัย webhook ของ OWASP Cheat Sheet Series คือ timestamp ของ event เดินทางใน header เฉพาะและถูกป้อนเข้าสู่การคำนวณลายเซ็น ดังนั้น timestamp ที่ถูกดัดแปลงจะตรวจสอบไม่ผ่าน
- timestamp ใน body ใช้รูปแบบ RFC 3339 extended date-time ประกาศไว้ในโค้ด: RFC 3339 ไม่ได้ถูกดึงมาจากคลังข้อมูล RAG สำหรับหน้านี้
- ข้อความเหล่านี้เป็นคำแถลงความสามารถที่อิงจากซอร์สของผลิตภัณฑ์และข้อกำหนดที่อ้างอิง NextPDF ไม่ได้อ้างความสอดคล้องหรือการรับรองใด ๆ สำหรับพื้นผิวนี้
หมายเหตุการพัฒนา
หัวข้อที่มีชื่อว่า “หมายเหตุการพัฒนา”- ทุกคลาสประกาศ
strict_types=1และเป็นfinalWebhookRegistration,WebhookPayload,WebhookRetryPolicyและDeadLetterEntryเป็นfinal readonlyพร้อม promoted public property - โมดูลมี annotation
@sinceเป็น2.2.0สคีมาลายเซ็นที่ผูกกับ timestamp เป็น breaking change ที่บันทึกไว้ใน 3.1.0 - delivery engine รับ abstraction แบบ PSR-18/PSR-17 ดังนั้น HTTP client จำลองสามารถทดสอบเส้นทางการส่ง การลองใหม่ และ dead-letter ทั้งหมดแบบออฟไลน์ได้ logger มีค่าเริ่มต้นเป็น null ให้ inject logger แบบ PSR-3 ในการใช้งานจริง มิฉะนั้นความล้มเหลวจะปรากฏผ่านค่าที่คืนเท่านั้น
- การนำ implementation ฝั่งผู้รับควรใช้
hash_equals()สำหรับการเปรียบเทียบลายเซ็นและบังคับใช้หน้าต่างความสดใหม่กับX-NextPDF-Timestamp - การทดสอบขอบเขตที่แนะนำ: การลงทะเบียนที่ tenant ไม่ตรงกัน, การกระจายเมื่อรายการ event ว่างเปล่า, 4xx แบบ terminal, การลองใหม่จนหมด, URL ที่ถูกบล็อกแบบ SSRF, การปฏิเสธลายเซ็นที่ timestamp ถูกดัดแปลงเทียบกับ vector คงที่ และการจำกัดจำนวนความพยายามใน dead-letter
ขอบเขตการเผยแพร่
หัวข้อที่มีชื่อว่า “ขอบเขตการเผยแพร่”หน้านี้อธิบายเฉพาะพฤติกรรมที่สังเกตได้จากภายนอกและพื้นผิว API สาธารณะที่รองรับเท่านั้น เส้นทาง namespace ภายใน, คลาสตัวช่วย, ตารางกลไก, ชื่อไฟล์ runbook และคำนำหน้า ticket อยู่นอกขอบเขต
ดูเพิ่มเติม
หัวข้อที่มีชื่อว่า “ดูเพิ่มเติม”- Webhook — NextPDF Enterprise — หน้าความสามารถ: เวิร์กโฟลว์ การกำหนดค่า และตัวอย่างการลงทะเบียนที่ใช้งานจริง
- SaaS — เอกสารอ้างอิงเชิงลึก — เอกลักษณ์ของ tenant, API key และโควตา ซึ่งเป็นแหล่งที่มาของ
TenantContext - Metering — เอกสารอ้างอิงเชิงลึก — การกระจายการวัดการใช้งานด้วยวินัยการส่งแบบ PSR-18 เดียวกัน