Claude는 이제 생성하는 파일에 서명된 C2PA 출처 메타데이터를 첨부합니다. OpenAI의 이미지 모델도 마찬가지이고, Gemini도 마찬가지입니다. 이는 출처 신호가 처음으로 업로드 엔드포인트에 도달한다는 뜻입니다. 하지만 다른 사람이 파일을 보기 전에 파이프라인이 메타데이터를 삭제할 가능성이 높습니다.
악의적으로 삭제하는 것이 아닙니다. 기본 설정이 그렇습니다. sharp().resize()는 별도로 요청하지 않는 한 메타데이터가 없는 깨끗한 파일을 생성합니다. ImageMagick과 Pillow, 대부분의 이미지 CDN도 마찬가지입니다. 매니페스트가 포함된 파일을 처리하면 더 작은 JPEG가 생성되지만, 로그에는 아무것도 남지 않을 수 있습니다.
이 문제는 테스트할 수 있으며, 테스트도 복잡하지 않습니다. 일반적인 파이프라인에서 메타데이터가 사라지는 지점과 이를 증명하는 방법, CI에 왕복 검사를 연결해 재발을 막는 방법을 단계별로 살펴보겠습니다. Apidog는 오케스트레이션을, c2patool은 바이트 수준 검증을 담당합니다.
실제로 파괴되는 것
C2PA 매니페스트는 파일 컨테이너에 내장된 암호화 서명 블록입니다. 자산을 누가 서명했고 무엇을 주장했는지 기록합니다. 서명된 뒤 바이트가 변경되면 다시 서명하지 않는 한 리더가 이를 감지할 수 있습니다.
핵심은 컨테이너 수준의 메타데이터라는 점입니다. 컨테이너를 다시 작성하면 매니페스트가 사라집니다.
| 작업 | 매니페스트는 기본적으로 보존됩니까? |
|---|---|
| 바이트 단위 복사 또는 이동 | 예 |
sharp().resize().toBuffer() |
아니오 |
ImageMagick convert / magick
|
아니오 |
Pillow Image.save()
|
아니오 |
| PNG에서 WebP, JPEG에서 AVIF로 변환 | 아니오 |
| 이미지 CDN 자동 최적화 | 대부분 아니오 |
| 스크린샷 | 아니오 |
| 이미지 편집기에서 다시 저장 | 아니오 |
| 변환 없는 S3 업로드 | 예 |
“아니오”에 해당하는 작업은 일반적인 웹 앱이 이미지에 수행하는 작업입니다.
- 썸네일 생성
- 반응형 이미지 생성
- 형식 협상
- 개인 정보 보호를 위한 EXIF 제거
각 작업은 개별적으로 합리적이지만, 모두 출처 체인을 조용히 끝낼 수 있습니다.
개인 정보 보호를 위한 -strip 습관은 특히 주의해야 합니다. EXIF에는 GPS 좌표와 카메라 일련 번호가 포함될 수 있습니다. 위치 데이터를 제거하려고 모든 메타데이터를 삭제하면 C2PA 매니페스트도 함께 사라집니다. 두 목표를 모두 달성하려면 전체 메타데이터 블록을 삭제하지 말고 선택적으로 제거해야 합니다.
2분 안에 문제 증명하기
먼저 파이프라인에 문제가 있는지 확인합니다. 유효한 매니페스트가 포함된 파일이 하나 필요합니다. Claude가 생성한 이미지나 Content Authenticity Initiative의 서명된 샘플을 사용할 수 있습니다.
참조 CLI를 설치합니다.
cargo install c2patool
원본 파일이 실제로 서명되었는지 확인합니다.
c2patool fixtures/signed-sample.png
청구 생성자와 서명 상태가 포함된 JSON 보고서를 받아야 합니다. 다음으로 실제 스택을 통해 업로드한 뒤, 사용자가 접근하는 URL에서 파일을 다시 가져옵니다.
# 실제 엔드포인트를 통해 업로드
curl -sS -X POST https://api.example.com/v1/assets \
-H "Authorization: Bearer $API_TOKEN" \
-F "file=@fixtures/signed-sample.png" \
-o /tmp/upload.json
# 프론트엔드가 사용할 URL로 다시 가져오기
ASSET_URL=$(jq -r '.url' /tmp/upload.json)
curl -sS "$ASSET_URL" -o /tmp/roundtrip.png
# 매니페스트 확인
c2patool /tmp/roundtrip.png
결과는 보통 다음 세 가지 중 하나입니다.
- 유효한 보고서: 매니페스트가 보존되었습니다.
- 매니페스트를 찾을 수 없음: 파이프라인의 어떤 단계가 매니페스트를 제거했습니다.
- 유효성 검사 오류: 매니페스트는 남아 있지만 서명이 현재 파일의 바이트와 일치하지 않습니다. 파일을 수정한 뒤 이전 매니페스트를 남겨둔 상태로, 다운스트림 검증기에는 변조된 파일처럼 보입니다.
세 번째 결과는 특히 중요합니다. 변환 라이브러리가 픽셀을 다시 작성하면서 메타데이터 블록은 보존했을 가능성이 큽니다.
문제를 일으키는 단계 찾기
왕복 검사가 실패했다면 추측하지 말고 파이프라인을 이분법적으로 검사합니다. 각 단계가 끝날 때마다 매니페스트를 확인하면 삭제 지점을 빠르게 좁힐 수 있습니다.
1. 크기 조정 또는 썸네일 단계
가장 흔한 원인입니다. sharp에서는 명시적으로 메타데이터 보존을 요청하지 않으면 메타데이터가 삭제됩니다.
// C2PA 매니페스트를 삭제할 수 있습니다.
await sharp(input).resize(1200).toFile(output);
// 메타데이터 블록을 보존합니다.
await sharp(input)
.resize(1200)
.keepMetadata()
.toFile(output);
단, 블록을 보존하는 것만으로는 충분하지 않습니다. 픽셀이 변경되었기 때문에 원래 서명은 새 바이트에 대해 유효하지 않습니다.
출처 체인을 유지하려면 다음 두 작업이 모두 필요합니다.
- 변환된 출력의 메타데이터 블록을 보존합니다.
- 변환된 출력에 다시 서명하고, 변환을 작업 단언으로 기록합니다. 예를 들어
c2pa.resized를 사용할 수 있습니다.
Rust, Python, JavaScript, C용 c2pa 라이브러리는 이러한 작업을 지원합니다.
2. 형식 변환
AVIF 또는 WebP를 제공한다는 것은 새로운 컨테이너를 만든다는 의미입니다.
이 경우에도 다음 중 하나를 명확히 선택해야 합니다.
- 메타데이터를 보존하고 변환된 파일에 다시 서명합니다.
- 출처 체인이 해당 단계에서 끝난다는 사실을 명시합니다.
3. CDN
많은 이미지 CDN은 배포 시 파일을 다시 작성합니다. 일부 CDN은 Content Credentials를 보존하고 다시 서명하지만, 역사적으로 많은 CDN이 메타데이터를 제거해 왔습니다.
원본 URL이 아니라 사용자가 실제로 접근하는 배포 URL을 테스트해야 합니다. 원본만 확인하면 파이프라인이 정상이라는 잘못된 결과를 얻을 수 있습니다.
4. 업로드 정규화
수집 시 형식을 표준화하기 위해 파일을 다시 인코딩하는 서비스도 확인해야 합니다. 이 로직은 애플리케이션 코드가 아니라 별도의 인프라 리포지토리에 있어 쉽게 놓칠 수 있습니다.
CI에서 영구적인 테스트 만들기
일회성 curl은 현재 상태만 증명합니다. 다음 스프린트에 누군가 크기 조정 단계를 추가하는 것은 막지 못합니다. 검사를 CI에 포함해야 합니다.
서로 다른 도구가 서로 다른 작업을 잘 수행하므로 테스트를 두 계층으로 나눕니다.
첫 번째 계층: Apidog 왕복 테스트
오케스트레이션은 일반적인 연쇄 API 테스트로 구성합니다.
- 서명된 픽처를 업로드합니다.
- 응답에서 반환된 URL을 저장합니다.
- 실제 전달 경로를 통해 자산을 다시 가져옵니다.
- 반환된 응답을 검증합니다.
Apidog에서는 다음과 같이 두 단계의 테스트 시나리오를 만들 수 있습니다.
단계 1: POST /v1/assets
- 본문: 서명된 픽처가 첨부된
multipart/form-data - 상태 코드:
201 - 응답: API 스키마와 일치
- 다음 단계에서 사용할 URL: 응답 후 스크립트로 환경 변수에 저장
파일 업로드 방식은 Apidog에서 파일 업로드 API 테스트하기와 동일합니다.
const body = pm.response.json();
pm.environment.set("ASSET_URL", body.url);
pm.test("업로드는 배포 URL을 반환합니다", function () {
pm.expect(body.url)
.to.be.a("string")
.and.to.include("https://");
});
단계 2: GET {{ASSET_URL}}
다음 항목을 검증합니다.
- 상태 코드가
200인지 확인합니다. -
Content-Type이 예상한 형식인지 확인합니다. - 응답 본문 크기가 업로드한 파일과 크게 다르지 않은지 확인합니다.
크기가 크게 줄었다면 파일이 다시 인코딩되었을 가능성이 있습니다.
const uploadedBytes = Number(pm.environment.get("FIXTURE_BYTES"));
const returnedBytes = pm.response.responseSize;
pm.test("자산이 조용히 다시 인코딩되지 않았습니다", function () {
pm.expect(returnedBytes).to.be.above(uploadedBytes * 0.9);
});
파일 크기는 증거가 아니라 휴리스틱입니다. 다만 큰 변화를 저렴하게 감지할 수 있고, 다른 API 테스트와 같은 스위트에서 실행할 수 있습니다. 표준 단언 패턴은 API 단언에서 확인할 수 있습니다.
두 번째 계층: CI의 바이트 수준 검사
서명을 검증하려면 컨테이너를 파싱해야 합니다. 이는 일반 HTTP 클라이언트가 아니라 c2patool이 담당할 작업입니다.
왕복으로 가져온 파일을 CI 단계에서 검사합니다.
# .github/workflows/provenance.yml
name: provenance
on: [pull_request]
jobs:
c2pa-round-trip:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: c2patool 설치
run: cargo install c2patool
- name: Apidog CLI 설치
run: npm install -g apidog-cli
- name: 왕복 시나리오 실행
run: |
apidog run --access-token "$APIDOG_ACCESS_TOKEN" \
-t "$SCENARIO_ID" \
-e "$ENV_ID" \
-r cli,html \
--out-dir ./apidog-reports
env:
APIDOG_ACCESS_TOKEN: ${{ secrets.APIDOG_ACCESS_TOKEN }}
SCENARIO_ID: ${{ vars.PROVENANCE_SCENARIO_ID }}
ENV_ID: ${{ vars.APIDOG_ENV_ID }}
- name: 매니페스트 보존 여부 확인
run: |
set -euo pipefail
curl -sS "$ASSET_URL" -o /tmp/roundtrip.png
c2patool /tmp/roundtrip.png > /tmp/report.json
jq -e '.validation_status == null or (.validation_status | length) == 0' /tmp/report.json
set -euo pipefail은 중요합니다. 이 설정이 없으면 c2patool이 실패해도 경고만 발생하고 빌드가 성공할 수 있습니다. 이는 방지하려는 실패를 그대로 통과시키는 결과입니다.
파이프라인에서 Apidog 시나리오를 실행하는 방법은 GitHub Actions에서 API 테스트 자동화하기에서 확인할 수 있습니다.
세 번째 계층(선택 사항): 검증 엔드포인트
출처 검증이 내부 테스트가 아니라 제품 기능이라면, 자체 서비스에 검증 엔드포인트를 두는 편이 깔끔합니다.
이 엔드포인트는 c2pa 라이브러리를 실행하고 구조화된 결과를 JSON으로 반환합니다. 그러면 전체 흐름을 일반적인 API 테스트로 검증할 수 있고, 프론트엔드는 파일을 직접 추측하지 않고 명확한 상태를 받을 수 있습니다.
{
"asset_id": "img_9f2c41",
"provenance": {
"status": "verified",
"standard": "c2pa",
"signer": "Anthropic",
"signature_valid": true,
"checked_at": "2026-08-11T09:14:22Z",
"tool": "c2patool/0.9"
}
}
상태는 두 가지가 아니라 최소 세 가지로 관리해야 합니다.
-
verified: 매니페스트가 있고 서명이 유효함 -
absent: 매니페스트가 없음 -
invalid: 매니페스트는 있지만 서명이 유효하지 않음
absent와 invalid를 하나의 불리언 값으로 합치면 중요한 신호를 잃게 됩니다.
검증기를 사용할 수 없는 상황이 있다면 unchecked도 추가하십시오. 검증 중단을 정상적인 결과처럼 처리하지 않도록 해야 합니다.
OpenAPI 정의에 응답 구조를 문서화하고 이를 검증하면 리팩터링 과정에서 필드가 사라지는 문제를 방지할 수 있습니다. 자세한 내용은 OpenAPI 사양 유효성 검사 방법을 참고하십시오.
유지할 가치가 있는 네 가지 픽처
출처 테스트는 정상 입력뿐 아니라 의도적으로 손상된 입력도 포함해야 합니다.
-
유효하게 서명된 파일
-
verified를 예상합니다. - 과도한 메타데이터 제거를 감지합니다.
-
-
매니페스트가 제거된 파일
- 동일한 이미지에서
exiftool -all=로 매니페스트를 제거합니다. -
absent를 예상합니다. -
verified가 나오면 안 됩니다.
- 동일한 이미지에서
-
변조된 파일
- 서명 후 바이트를 변경한 파일입니다.
-
invalid를 예상합니다. - 매니페스트의 존재뿐 아니라 서명 자체를 검증하고 있음을 확인할 수 있습니다.
-
지원되지 않는 형식
- 매니페스트를 지원하지 않는 형식입니다.
- 500 오류가 아니라 정상적인
absent를 예상합니다.
네 가지 픽처를 모두 테스트 시나리오와 함께 리포지토리에 커밋하십시오. 작고 변경되지 않는 픽처를 사용해야 테스트가 안정적으로 유지됩니다.
왜 테스트해야 하는가
제품 주장
UI에 출처 배지를 표시하지만 파이프라인이 매니페스트를 제거한다면, 크기 조정된 모든 자산의 배지가 잘못된 정보가 됩니다. 사용자가 이를 발견하면 제품 신뢰도 문제로 이어집니다.
규정 준수
Article 50과 관련해 C2PA에 의존하고 있다면, 파이프라인이 매니페스트를 제거하는 순간 해당 통제 수단은 작동하지 않습니다. API 개발자를 위한 EU AI법 Article 50에서 관련 의무를 확인할 수 있습니다.
출처 신호 자체
출처는 체인이 처음부터 끝까지 유지될 때만 유용합니다. 매니페스트를 조용히 삭제하는 파이프라인은 전체 생태계의 검증 가능성을 낮춥니다.
자체 엔드포인트에 왕복 시나리오를 구축하려면 Apidog 다운로드 후 c2patool 검증 단계를 연결하십시오.
FAQ
이미지 크기를 조정하면 C2PA 메타데이터가 제거됩니까?
일반적인 이미지 라이브러리에서는 기본적으로 제거될 수 있습니다. 메타데이터 블록을 보존하려면 명시적인 플래그가 필요합니다. 또한 변환 후에도 유효한 서명을 유지하려면 출력 파일에 다시 서명해야 합니다.
파일에 C2PA 메타데이터가 있는지 어떻게 확인합니까?
명령줄에서 다음 명령을 실행합니다.
c2patool <file>
또는 파일을 Content Credentials 확인 페이지에 업로드할 수 있습니다.
크기를 조정한 뒤에도 C2PA 메타데이터를 유지할 수 있습니까?
가능합니다. 하지만 메타데이터 블록을 보존하는 것만으로는 충분하지 않습니다.
- 변환 과정에서 블록을 보존합니다.
-
c2pa라이브러리로 출력에 다시 서명합니다. -
c2pa.resized와 같은 작업 단언을 기록합니다.
그렇지 않으면 이전 서명이 새 파일의 바이트와 일치하지 않습니다.
CDN은 Content Credentials를 제거합니까?
자동 최적화 과정에서 많은 CDN이 제거할 수 있습니다. 일부 CDN은 기본적으로 보존하고 다시 서명합니다. 반드시 원본 URL이 아니라 사용자가 접근하는 배포 URL을 테스트하십시오.
제거된 매니페스트와 유효하지 않은 매니페스트의 차이점은 무엇입니까?
-
absent: 매니페스트를 찾을 수 없음. 파일의 출처에 대해 아무것도 확인할 수 없습니다. -
invalid: 매니페스트는 있지만 서명이 파일의 바이트와 일치하지 않음. 서명 후 파일이 변경되었을 가능성이 있습니다.
두 상태를 별도로 관리해야 합니다.
Apidog가 C2PA 서명을 직접 확인할 수 있습니까?
Apidog는 왕복 테스트를 오케스트레이션하고 검증 엔드포인트가 반환한 JSON을 단언합니다. 서명 파싱 자체는 CI 단계나 자체 서비스에서 실행하는 c2patool의 역할입니다. 두 도구를 함께 사용하면 됩니다.
개인 정보 보호를 위해 EXIF를 제거하되 C2PA는 유지해야 합니까?
그것이 올바른 목표라면 선택적으로 메타데이터를 제거해야 합니다. 포괄적인 -strip은 EXIF와 C2PA를 모두 제거할 수 있습니다. 필요한 EXIF 블록만 제거하고 C2PA 매니페스트는 유지하십시오.
핵심 요점
출처 메타데이터는 API에 온전하게 도착하더라도 이미지 처리 파이프라인에서 조용히 사라질 수 있습니다. 이를 방지하려면 다음 두 가지를 구현하십시오.
- 실제 전달 경로를 검증하는 Apidog 왕복 시나리오
- CI에서 빌드를 실패시키는
c2patool바이트 수준 검사
약 20분의 설정만으로 UI에서 표시하는 출처 주장이 실제 파이프라인에서도 보장되는지 지속적으로 확인할 수 있습니다.
Top comments (0)