AI 에이전트를 위한 Docusign을 만들었습니다 — 방법은 이렇습니다
Source: Dev.to
AI 에이전트는 계약을 초안하고, 조건을 협상하며, 문구를 최종 확정할 수 있지만, 서명이 필요해지는 순간 워크플로가 끊깁니다. 기존 전자 서명 서비스(DocuSign, HelloSign, Adobe Sign)는 브라우저, OAuth 흐름 또는 수동 단계를 기반으로 하며, 인간이 아닌 발신자에게는 적합하지 않습니다.
저는 signb.ee를 만들었습니다 – AI 에이전트를 위해 설계된 문서 서명 인프라입니다.
signb.ee 소개
signb.ee는 마크다운(대부분의 LLM이 기본 출력 형식) 을 받아 전체 서명 절차를 처리하는 단일 API 호출을 제공합니다:
- 마크다운을 깔끔한 PDF로 변환합니다
- 발신자를 검증합니다 (API 키 또는 이메일 OTP)
- 수신자에게 서명 링크가 포함된 이메일을 보냅니다
- 양측이 서명 스타일을 선택하고 서명할 수 있게 합니다
- 변조 방지 서명 인증서가 포함된 SHA‑256 인증 PDF를 반환합니다
SDK도 없고, OAuth 절차도 없으며, 브라우저 자동화도 필요 없습니다.
API 예시
curl -X POST https://signb.ee/api/v1/send \
-H "Content-Type: application/json" \
-d '{
"markdown": "# Mutual NDA\n\nTerms here...",
"sender_name": "Alice",
"sender_email": "alice@company.com",
"recipient_name": "Bob",
"recipient_email": "bob@acme.com"
}'signb.ee 작동 방식
- Markdown → PDF – 서비스가 마크다운을 PDF로 렌더링합니다.
- 보낸 사람 인증 –
- API 키 없이: 보낸 사람에게 이메일 OTP가 전송됩니다.
- API 키와 함께: 보낸 사람이 사전 인증되어 OTP가 생략됩니다.
- 수신자 흐름 – 수신자는 서명 링크가 포함된 이메일을 받고, 서명 스타일을 선택한 뒤 서명합니다.
- 인증서 – 양 당사자는 SHA‑256 해시와 서명 인증서가 포함된 PDF를 받습니다.
구현 세부 사항
PDF 생성
원래는 Puppeteer(HTML → 스크린샷 → PDF)를 사용해 보았지만, 50 MB 크기의 Chromium 바이너리 때문에 서버리스 환경에서 콜드 스타트가 크게 발생했습니다. 순수 JavaScript PDF 라이브러리인 pdf‑lib 로 전환하면서 네이티브 의존성이 사라지고 번들 크기가 95 % 감소했습니다.
import { PDFDocument, rgb, StandardFonts } from "pdf-lib";
const pdfDoc = await PDFDocument.load(originalPdfBytes);
const page = pdfDoc.addPage([595, 842]); // A4
const helveticaBold = await pdfDoc.embedFont(StandardFonts.HelveticaBold);
page.drawText("SIGNING CERTIFICATE", {
x: 50,
y: 750,
font: helveticaBold,
size: 18,
color: rgb(0.1, 0.1, 0.1),
});
// ... add signatures, timestamps, SHA‑256 hash콜드 스타트 시간이 약 8 초에서 < 500 ms 로 감소했습니다.
인증 옵션
| 모드 | 작동 방식 |
|---|---|
| API‑key | 발신자가 사전에 인증되어 있으며, 수신자는 즉시 서명 링크를 받습니다. |
| OTP | 발신자는 일회용 코드를 포함한 이메일을 받으며, 사전 설정 없이 최소한의 마찰로 진행됩니다. |
Cookie Bug with BetterAuth
프로덕션 환경에서는 HTTPS에서 인증 쿠키가 __Secure- 접두사가 붙었지만, 미들웨어는 better-auth.session_token만 찾고 있었습니다. 해결 방법은 한 줄 코드입니다:
// Before (broken in production)
const session = request.cookies.get("better-auth.session_token");
// After (works everywhere)
const session =
request.cookies.get("__Secure-better-auth.session_token") ||
request.cookies.get("better-auth.session_token");HTTPS에서 BetterAuth를 사용할 경우, 두 쿠키 이름을 모두 확인하도록 하세요.
엔드‑투‑엔드 흐름
- Agent →
POST /api/v1/send- Markdown → PDF, 블롭 스토리지에 업로드
- 보낸 사람은 OTP 이메일을 받음(또는 사전 인증됨)
- Sender가 인증 링크를 클릭 → 계정을 생성하고, 서명 스타일을 선택하고, 서명 → 수신자가 서명 링크를 받음
- Recipient가 링크를 클릭 → PDF를 검토하고, 서명 스타일을 선택하고, 서명 → 두 사람 모두 인증서가 포함된 최종 PDF를 받음
서명 인증서 내용
- 양 당사자의 이름 및 서명
- 각 서명의 UTC 타임스탬프
- 서명자의 IP 주소
- 전체 문서의 SHA‑256 해시
- 검증 URL
향후 작업
- MCP server discovery – 에이전트(Claude, Cursor, Windsurf 등)가 도구 설명을 통해 signb.ee를 자동으로 발견하도록 하여 수동 문서가 필요 없게 함.
- Webhook notifications – 문서가 완전히 서명되면 웹훅을 발생시켜 이메일에 의존하지 않고 완전 자동화된 에이전트 워크플로를 가능하게 함.
API 가용성
API는 **https://signb.ee**에서 라이브로 제공되며, 무료 티어(월 5문서)를 제공합니다. 신용카드가 필요하지 않습니다.
에이전트 스킬 설치
npx skills add signbee/skill --skill signbee -gOpenAPI 사양과 llms.txt는 에이전트가 사용할 수 있도록 제공됩니다.
피드백
API 설계에 대한 피드백을 찾고 있습니다, 특히 에이전트 워크플로를 구축하는 분들의 의견을 듣고 싶습니다. 무엇이 부족한가요? 여러분의 에이전트에 더 유용하게 만들려면 무엇이 필요할까요?