콘텐츠로 이동

프로덕션에서 NextPDF 운영하기

Spec: ISO 9241-112:2025, §6.1.2.3 Spec: ISO/IEC/IEEE 26514:2022, §3.x162 Evidence: Artifact-backed

프로덕션에서 PDF 엔진을 운영한다는 것은 “호출하고 바이트를 내보내면 끝”나는 일이 아닙니다. 렌더링이 정상일 때 엔진이 무엇을 알려 주는지, 정상이 아닐 때 어떻게 동작하는지, 관측성을 위해 어디를 연결해야 하는지, 그리고 어떤 위험한 작업을 조용히 수행하지 않고 거부하는지는 모두 사용자가 파악해야 할 부분입니다. 이 페이지는 운영 표면, 즉 NextPDF가 실제로 가동되는 날 팀이 책임져야 하는 이음새와 속성을 설명합니다.

문서 엔진은 일반적인 서비스와는 다른 방식으로 실패합니다. 이러한 실패는 흔히 조용하게 발생합니다. 파일은 만들어 내지만 저하된 레이아웃, 출력을 바꿔 버리는 차단된 외부 리소스, 서명된 것처럼 보이지만 실제로는 서명되지 않은 문서 등이 그 예입니다. 엔진이 이런 문제를 숨기면, 대시보드가 아니라 고객을 통해 발견하게 됩니다. 엔진이 이를 드러내면, 그 문제들은 장애가 아니라 알림과 런북 항목으로 다룰 수 있습니다.

따라서 운영성은 나중에 추가하는 기능이 아닙니다. 운영성은 엔진이 각 렌더링에 대해 진실을 알려 주도록 설계되었는지의 문제이며, NextPDF는 그렇게 설계되었습니다.

  • 모든 렌더링은 구조화된 보고서를 생성합니다. 성공 여부, 페이지 수, 렌더링 시간, 최대 메모리, 경고 코드, 폴백 발생, 차단된 외부 리소스 등을 포함하며, 대시보드를 위해 JSON으로 직렬화할 수 있습니다.
  • 엔진은 PSR-14 디스패처를 통해 타입 지정 수명 주기 이벤트를 내보냅니다 — 수신자가 없을 때는 오버헤드가 전혀 없으며, 감사 및 메트릭 후크가 바로 그 지점에 연결됩니다.
  • 실패 모드는 명시적이며, 조용하지 않습니다. 저하된 동등성은 보고됩니다. 고수준 서명 표면은 빠르게 실패합니다. 출력은 원자적으로 기록됩니다. 인프로세스 HTML 경로에서는 외부 하위 리소스 가져오기가 구조적으로 비활성화되어 있습니다.
  • 위험한 작업은 Connect에서 사람의 개입을 요구합니다. NextPDF가 AI 에이전트에 노출될 때, 파괴적이거나 프라이버시에 중요한 도구는 확인 챌린지 뒤에서 게이트로 보호됩니다. 이는 가장 중요한 운영 속성으로, 사용자가 보게 되는 위치에 명시되어 있습니다(ISO 9241-112 §6.1.2.3).

운영 모델은 하나의 원칙을 기반으로 합니다. 렌더링은 자신이 한 일에 대해 결코 거짓말해서는 안 됩니다. 세 가지 메커니즘이 이를 구체화합니다 — 보고서, 이벤트 스트림, 그리고 일련의 안전 장치 동작입니다. 엔진이 에이전트에 의해 구동될 때는 네 번째 메커니즘이 적용됩니다.

  1. Observe each render Collect the per-render report — success, timing, peak memory, warnings, fallbacks, blocked-resource counts — into your telemetry sink.
  2. Subscribe to lifecycle events Attach PSR-14 listeners for document, security, and serialization events for audit logging and metrics.
  3. Detect degradation Treat degraded-parity and fallback signals as health indicators, not noise. They mean the output differs from the ideal render.
  4. Gate the dangerous path In Connect, route destructive or privacy-critical operations through the human confirmation gate before they execute.
엔드 투 엔드 운영 표면입니다. 계측은 옵트인 방식이며 사용하지 않을 때는 비용이 들지 않습니다. 실패 모드는 데이터나 빠른 실패로 드러나며, 결코 조용히 잘못된 파일로 나타나지 않습니다.

보고서는 집계를 위해 설계된 불변 스냅샷입니다. 보고서는 렌더링 성공 여부, 소요 시간, 최대 메모리, 코드별 경고 수, 안전 렌더링 모드 활성화 여부, 거부된 외부 리소스 요청 수, 그리고 어떤 레이아웃 폴백이 발생했는지를 담고 있습니다. 마지막 항목군은 운영상 중요합니다. 플릿 전반에 걸쳐 “flex가 block으로 폴백됨” 횟수가 증가하는 것은 템플릿이 변경되었다는 신호이며, 어떤 사용자가 불만을 제기하기 전에 이를 알아챌 수 있습니다.

이벤트 이음새는 PSR-14와 호환되며 의도적으로 가볍게 설계되었습니다. 디스패처는 이벤트 클래스에 등록된 리스너가 없을 때 즉시 반환합니다. 그 덕분에 이음새를 추가해도 실제로 사용하기 전까지는 아무런 비용이 들지 않습니다. 문서 생성 및 출력, 페이지 추가, 콘텐츠 및 폰트 로딩, 암호화 적용, 서명 적용, PDF 직렬화에 대해 타입 지정 이벤트가 있습니다. 바로 이러한 지점이 감사 로그나 메트릭 카운터가 실제로 관심을 갖는 부분입니다. 관측성 계약(메트릭 카운터, 게이지, 히스토그램, 트레이스 스팬, HSM 감사 로그)은 no-op 구현과 함께 제공됩니다. 따라서 엔진은 텔레메트리 배선이 전혀 없어도 완전히 동작하며, 실제 구현을 바인딩하면 관측 가능해집니다.

이 페이지는 아티팩트 기반입니다. 운영 표면은 지금 바로 배선할 수 있는 실제 클래스와 계약입니다. Evidence: Artifact-backed

보고서는 코드입니다. RenderReport는 설명된 필드를 정확히 갖춘 불변 값 객체이며 JSON으로 직렬화할 수 있습니다 — 성공 여부, 페이지 수, 렌더링 시간, 최대 메모리, 코드별 경고 수, 안전 모드 플래그, 외부 리소스 거부, 폴백 발생, 타임스탬프입니다. 이벤트 이음새는 코드입니다. 오버헤드가 없는 빠른 경로와, 문서·보안·콘텐츠·라이터 이벤트를 아우르는 타입 지정 이벤트 계층을 갖춘 PSR-14 EventDispatcher입니다. 안전 장치 동작은 코드입니다. 원자적 출력 기록은 문서화된 time-of-check/time-of-use 간극을 막습니다. 인프로세스 HTML 경로의 원격 하위 리소스 차단 보장은 구조적으로 강제되는 @security 계약입니다. 고수준 서명 표면은 서명되지 않은 PDF를 내보내는 대신 차단성 진단을 발생시킵니다.

에이전트 안전 속성은 NextPDF Connect의 코드입니다: Evidence: Code-backed 네 단계 위험 모델(안전, 주의, 검토, 승인 필요)과, 승인이 필요한 도구에 대해 일회용 챌린지 토큰을 발급하고, 사용자가 그 토큰을 되돌려 전달할 때까지 진행을 거부하는 확인 게이트입니다. 도구의 위험도는 정확히 두 가지 출처에서 비롯됩니다. 도구 자체의 선언과, 위험을 높이는 것만 가능한 운영자 재정의입니다. 따라서 위험 표면은 조용히 넓혀질 수 없습니다.

이 페이지가 구성된 방식 자체가 표준 기반입니다: Spec: ISO/IEC/IEEE 26514:2022, §3.x162 독자가 수행하는 작업(청크)에 따라 운영 정보를 구조화할 것을 권장하며, 이에 따라 네 단계가 관찰, 구독, 탐지, 게이트로 매핑됩니다.

아래 코드는 관측성 이음새를 보여줍니다. 수명 주기 이벤트와 렌더링 보고서를 텔레메트리로 변환하는 PSR-14 리스너입니다. 이 예제는 이음새를 보여 주기 위한 것입니다. 메트릭 싱크는 사용자가 정해야 합니다.

<?php
declare(strict_types=1);
use NextPDF\Event\Document\DocumentOutputEvent;
use NextPDF\Event\Security\SignatureAppliedEvent;
use Psr\Log\LoggerInterface;
/**
* Audit + metrics listener for production operation.
*
* Attaching this costs nothing until events fire — the dispatcher
* short-circuits when no listener is registered for an event class.
*/
final readonly class OperationsListener
{
public function __construct(
private LoggerInterface $logger,
) {}
public function onSignatureApplied(SignatureAppliedEvent $event): void
{
// Compliance trail: who signed, at what level, why.
$this->logger->info('pdf.signature.applied', [
'level' => $event->signatureLevel,
'signer' => $event->signerName,
'reason' => $event->reason,
]);
}
public function onDocumentOutput(DocumentOutputEvent $event): void
{
// Pair this with the engine's RenderReport for the full picture:
// success, render_time_ms, peak_memory_bytes, fallback_occurrences.
$this->logger->info('pdf.document.output', [
'event' => $event::class,
]);
}
}

핵심은 본문이 아니라 이음새입니다. 엔진은 타입 지정 이벤트와 구조화된 보고서를 건네줍니다. 무엇을 전달하고 샘플링하며 알림으로 띄울지는 엔진이 의도적으로 사용자에게 맡기는 운영 결정입니다.

운영상 흔한 오해는 *“바이트를 반환했으면 성공한 것이다.”*라는 것입니다. 렌더링은 성공해도 여전히 저하될 수 있습니다. 레이아웃이 폴백되거나, 외부 이미지가 차단되어 조용히 빠져 있거나, 어떤 기능이 활성 모드에서 지원되지 않았을 수 있습니다. 바이트는 존재합니다. 하지만 그 문서는 템플릿이 의도한 것이 아닙니다. 엔진이 이를 경고와 폴백 횟수로 보고하는 것은 바로 “바이트 반환”이 “올바르게 렌더링됨”으로 오인되지 않도록 하기 위함입니다. 반환 값을 유일한 성공 신호로 취급하는 것이야말로 이 표면이 방지하고자 존재하는 오류입니다.

Connect에 특화된 두 번째 오해는, 도구가 “그저 렌더링만 한다”는 이유로 PDF 도구를 에이전트에 노출하는 것이 안전하다는 생각입니다. 파괴적이거나, 덮어쓰거나, 프라이버시에 중요한 작업이 사람의 확인 챌린지 뒤에서 게이트로 보호되는 데는 이유가 있습니다. 그 게이트를 우회하거나 자동으로 응답하는 것은 게이트가 제거하는 바로 그 위험을 다시 들여오는 것입니다.

  • 엔진은 계측을 제공할 뿐, 사용자의 관측성 스택을 운영하지는 않습니다. 엔진은 보고서와 타입 지정 이벤트를 내보냅니다. 수집, 알림, 대시보드, 보존은 사용자의 몫입니다.
  • no-op 관측성이 기본값입니다. 메트릭, 트레이스, HSM 감사 로그는 사용자가 실제 구현을 바인딩하기 전까지 비활성 상태입니다 — 엔진이 배선 없이도 동작하도록 의도된 설계입니다. 하지만 이는 사용자가 옵트인하기 전까지 아무것도 기록되지 않는다는 뜻입니다.
  • SSRF 안전 장치는 인프로세스 HTML 경로에 적용됩니다. 외부 렌더러 브리지(브라우저/Office)는 본질적으로 아웃바운드 호출을 수행하며 자체적인 전송 강화를 갖추고 있습니다. 이 보장은 구체적으로 인프로세스 경로에 관한 것입니다.
  • 사람 확인 게이트는 NextPDF Connect의 속성입니다. 이는 에이전트 주도 호출을 관장합니다. 이는 일반적인 PDF 기능이 아니며, 인수 해싱이 아니라 도구 이름과 nonce에 바인딩됩니다.
  • 고수준 서명 표면은 빠르게 실패합니다. 이는 배선된 서명자가 아닙니다. 운영상 그 진단을 신호로 취급하고, 실제 서명은 배선된 하위 수준 경로를 사용해 수행해야 합니다.
  • 이 페이지는 아티팩트 기반입니다. 언급된 모든 이음새는 실제 클래스나 계약이지만, 이를 제대로 운영하는 것은 사용자의 책임입니다.
Observability and operational seams — edition availability
Edition Availability
Core

RenderReport, PSR-14 이벤트 디스패처와 타입 지정 이벤트 계층, no-op 관측성 계약, 원자적 출력 기록, 그리고 인프로세스 SSRF 안전 장치는 모두 Core입니다.

Pro

서명이 사용될 때 운영상 실질적 의미를 갖는 보안 수명 주기 이벤트 (암호화/서명 적용)를 추가합니다.

Enterprise

HSM 감사 로그 이음새와 운영 신호로 쓰이는 검증 결과를 추가합니다. NextPDF Connect는 에이전트 주도 고위험 작업을 위한 사람 확인 게이트를 추가합니다.

  • 파이프라인 모델 — 이러한 관측성 이음새를 가능하게 하는 단계적 구조와 그 위치입니다.
  • HSM 기반 서명 — 하드웨어 기반 키의 운영 형태와 감사 경계의 위치입니다.
  • 대량 문서 생성 — 대규모 환경에서 렌더링별 보고서를 용량 및 상태 신호로 전환합니다.
  • RenderReport — 기본 상태 신호로 사용되는, 엔진의 불변 렌더링별 메트릭 스냅샷이며 JSON으로 직렬화할 수 있습니다.
  • PSR-14 — 이벤트 디스패처를 위한 PHP 표준입니다. NextPDF의 디스패처는 이와 호환되며 사용하지 않을 때는 오버헤드가 없습니다.
  • 저하된 동등성 — 완료는 되었지만 어떤 기능이 폴백되었거나 지원되지 않아 출력이 이상적인 결과와 다른 렌더링입니다.
  • 폴백 발생 — 레이아웃 엔진이 더 단순한 동작으로 대체한 기록된 사례입니다(예: flex가 block으로 렌더링됨).
  • SSRF(Server-Side Request Forgery) — 서버를 속여 내부 대상에 요청을 보내게 만드는 공격입니다. 인프로세스 HTML 경로에서는 구조적으로 제거됩니다.
  • 확인 게이트 — 고위험 에이전트 호출 도구가 실행되기 전에 사람이 전달하는 일회용 토큰을 요구하는 NextPDF Connect 메커니즘입니다.
  • 원자적 기록 — 동시에 읽는 쪽이 이전 파일이나 완전한 새 파일 중 하나만 보게 되고 결코 부분 파일은 보지 않는 출력 기록입니다.