Zero-build 개인정보 보호정책 with Astro

발행: (2026년 4월 10일 오후 05:13 GMT+9)
6 분 소요
원문: Hacker News

Source: Hacker News

우리가 3월에 OpenPolicy Astro 통합을 출시했을 때는 빌드 시에 Markdown 파일을 생성하는 방식으로 동작했습니다. astro.config.mjs에 플러그인을 추가하고, 출력 디렉터리를 지정하면 Astro가 생성된 .md 파일을 컴포넌트로 가져왔습니다.

// astro.config.mjs — old approach
import { openPolicy } from "@openpolicy/astro";

export default defineConfig({
  integrations: [
    openPolicy({
      formats: ["markdown"],
      outDir: "src/generated/policies",
    }),
  ],
});

동작은 했지만, 추가 패키지, 생성된 디렉터리를 위한 .gitignore 항목, 그리고 설정과 페이지 사이에 파일 감시 단계라는 마찰이 생겼습니다.

핵심 라이브러리는 이제 정책을 직접 컴파일합니다. Astro의 frontmatter에서 바로 호출할 수 있으니, 통합도 필요 없고 생성 파일도 필요 없습니다.

Install

bun add @openpolicy/sdk @openpolicy/core @openpolicy/renderers

Astro 통합이 필요 없습니다. Vite 플러그인도 없습니다. 세 개의 패키지.

구성 정의하기

Create src/lib/openpolicy.ts:

import { defineConfig } from "@openpolicy/sdk";

export default defineConfig({
  company: {
    name: "Acme",
    legalName: "Acme, Inc.",
    // ...
  },
  privacy: {
    effectiveDate: "2026-04-01",
    dataCollected: { /* ... */ },
    jurisdictions: ["us", "eu"],
    // ...
  },
  cookie: {
    effectiveDate: "2026-04-01",
    cookies: [ /* ... */ ],
    // ...
  },
  terms: {
    effectiveDate: "2026-04-01",
    governingLaw: { jurisdiction: "Delaware, USA" },
    // ...
  },
});

사용 가능한 모든 필드에 대해서는 전체 구성 스키마를 확인하세요.

이를 가장 빠르게 채우는 방법은 기존 개인정보 보호 페이지(또는 앱에 대한 설명)를 Claude에 붙여넣고 구성 파일을 생성하도록 요청하는 것입니다. 출력이 결정적이기 때문에—같은 구성은 항상 동일한 정책을 생성합니다—Claude는 설정만 수행하고 법적 텍스트를 작성하지 않습니다. 입력을 검토하면 OpenPolicy가 나머지를 처리합니다.

전용 페이지에 렌더링

각 페이지는 설정(config)에서 정책을 찾아 컴파일하고, 프런트매터 안에서 HTML로 렌더링합니다:

---
// src/pages/privacy.astro
import { compile, expandOpenPolicyConfig } from "@openpolicy/core";
import { renderHTML } from "@openpolicy/renderers";
import openpolicy from "../lib/openpolicy";

const policies = expandOpenPolicyConfig(openpolicy);
const privacyPolicy = policies.find((p) => p.type === "privacy");

if (!privacyPolicy) {
  throw new Error("Privacy policy not found in config");
}

const policy = renderHTML(compile(privacyPolicy));
---
    
    Privacy Policy

expandOpenPolicyConfig는 통합 설정을 개별 정책으로 분리합니다. compile은 각 정책을 해당 섹션 빌더를 통해 처리합니다. renderHTML은 결과를 HTML 문자열로 변환합니다. set:html은 이 문자열을 이스케이프 없이 렌더링합니다.

모든 작업은 빌드 시점에 실행됩니다. 브라우저로 전송되는 JavaScript는 전혀 없습니다.

약관 및 쿠키 페이지도 동일한 방식으로 동작합니다 — type === "terms" 또는 type === "cookie"을 찾아서 사용하면 됩니다.

astro.config.mjs

import { defineConfig } from "astro/config";

export default defineConfig({});

통합이 없습니다. 플러그인이 없습니다. 설정할 것이 없습니다.

왜 이것이 이전 접근 방식보다 간단한가

플러그인 방식은 src/ 디렉터리 안에 중간 파일을 생성했습니다. 이 방식은 그렇지 않습니다:

  • 생성된 파일이 없음. src/generated/ 디렉터리를 만들거나 관리하거나 git에서 제외할 필요가 없습니다.
  • 플러그인 설정이 없음. astro.config.mjs는 비워 둡니다. outDir, formats, 감시 경로 등이 없습니다.
  • 추가 패키지가 없음. @openpolicy/astro를 제거하고, 런타임에는 corerenderers만 필요합니다.
  • 세 가지 정책 유형 모두 지원. 개인정보, 이용 약관, 쿠키 정책이 하나의 설정 파일에서 컴파일됩니다. 동일한 defineConfig() 호출, 동일한 파이프라인.

출력은 이전과 동일합니다: 클라이언트‑사이드 JavaScript 없이 정적으로 렌더링된 HTML. 차이점은 컴파일이 플러그인이 파일 시스템을 감시하면서 발생하는 부수 효과가 아니라, 이를 사용하는 페이지 안에서 인라인으로 이루어진다는 점입니다.

전체 작업 예시는 레포지토리의 examples/astro 디렉터리에 있습니다.

Going further with OpenPolicy+

If you need more than static generation, OpenPolicy+ extends the core library with cloud‑based consent tracking, PR automation (policy linting, compliance checks on every pull request), and hands‑on onboarding from our team. Book a demo and we’ll help you get set up.

0 조회
Back to Blog

관련 글

더 보기 »