05 · 어댑터
시크릿을 판단하는 건 코어입니다. 텍스트는 누군가 가져다줘야 합니다.
텍스트를 가져와 코어에 넘기고 결과를 돌려주는 패키지 여섯 개입니다. 판단은 하지 않습니다.
해결하는 문제
복사한 예제는 이제 직접 관리해야 하는 포크입니다
이전
예제 폴더에서 pino-redact.mjs를 복사합니다. 지금은 잘 동작합니다. 하지만 pino 다음 메이저 버전에서 훅 시그니처가 바뀌어도 알려 주는 사람이 없습니다.
지금
npm install @redact-secret/adapter-pino. 지원하는 pino 버전 범위가 명시되어 있고 범위의 양 끝 버전에서 테스트하며, tarball 안에 자체 changelog가 들어 있습니다.
복사한 파일에는 버전도 changelog도 없고, 호스트 SDK 계약이 바뀌어도 알려 주는 곳이 없습니다. 이 저장소는 연결 코드를 코어로 옮기지 않고 이 문제를 해결하려고 만들었습니다.
위치
호스트와 엔진 사이
Redact Secret 코어
무엇이 시크릿인지는 코어가 판단합니다. 어댑터는 판단하지 않습니다.
패키지
레지스트리 두 곳, 패키지 여섯 개
@redact-secret/adapter
다른 패키지가 모두 기반으로 삼는 공용 패키지입니다. 문자열 하나를 가리는 기본 함수와, 중첩 객체 안에서 문자열을 찾는 한도가 있는 탐색기(walker)가 들어 있습니다. 연동을 직접 만들 때만 따로 설치하면 됩니다.
@redact-secret/adapter-pino
값 기준으로 가리며, pino 자체의 경로 기반 redact와 함께 씁니다. pino는 메시지 문자열이나 오류 메시지 속 토큰을 보지 못하지만, 이 패키지는 찾아냅니다.
@redact-secret/adapter-otel
span과 이벤트의 문자열·문자열 배열 속성을 모두, span이 다음 processor로 넘어가기 전에 가립니다. 속성 이름을 허용 목록으로 제한하지 않으므로 OpenInference와 GenAI 규약도 따로 하드코딩하지 않고 처리합니다.
@redact-secret/adapter-ai-context
특정 프레임워크에 묶이지 않는 AI 작업용 경계입니다. 사용자 입력, 도구 결과, 조립한 컨텍스트, 스트리밍 텍스트를 모델에 닿기 전에 정리합니다. 특정 모델 벤더, 에이전트 프레임워크, 전송 방식을 전제하지 않습니다.
@redact-secret/adapter-mcp
Model Context Protocol 경계입니다. 도구 결과와 (선택적으로) 인자, 클라이언트가 resources/read로 읽는 내용을 검사합니다. 위 패키지를 얇게 특화해 MCP 형식만 더했습니다. 타입 정의용으로도 MCP SDK를 import하지 않습니다.
redact-secret-adapters
Python 표준 라이브러리에는 값 기반 가림 처리가 전혀 없습니다. 이 필터가 그 기능을 더하고, [otel] extra를 설치하면 span도 처리합니다.
Langfuse처럼 마스킹 콜백을 쓰는 호스트는 전용 패키지가 필요 없습니다. 공용 탐색기만으로 연동이 끝납니다.
버전과 호스트 범위는 2026-09-28 기준 npm·PyPI 레지스트리 값입니다.
설계 원칙
애매하면 마커를 출력합니다
모든 어댑터는 문자열을 가리는 기본 함수 하나를 공유하며, 이 함수는 오류가 나도 원문을 절대 내보내지 않습니다. 아래 마커는 공개 API입니다. 호스트가 실제로 보는 값이므로 메이저 버전에서만 바뀝니다.
| 마커 | 출력 조건 |
|---|---|
| [REDACTED:BLOCKED] | block 판정. 매치된 범위만이 아니라 값(leaf) 전체를 바꿉니다. |
| [REDACTED:ERROR] | 코어 호출 중 생긴 모든 실패. 코어가 초기화되지 않은 경우도 포함합니다. 원본 텍스트도, 오류 메시지 자체도 내보내지 않습니다. |
| [REDACTED:LIMIT_EXCEEDED] | 탐색 한도를 넘은 값. 검사하지 않으며, 가리지 않은 채 내보내지도 않습니다. |
| [REDACTED:CYCLE] | 자기 자신을 참조하는 객체. |
탐색 한도
문자열 하나당 200,000자 상한도 있습니다. 한도를 넘은 요소와 키는 통과시키지 않고 버립니다. 모든 한도는 호출마다 바꿀 수 있습니다.
작게 유지하는 이유
코어에서 가져오는 것은 네 가지뿐
- initialize()
- 엔진을 불러옵니다.
- scanAndRedact()
- 엔진이 돌려주는 결과의 형태.
- findings
- 결과가 배열이라는 점.
- finding.action
block인지warn인지.
선언한 호환 범위가 보호하는 것이 바로 이 네 가지입니다. 이 패키지들은 코어가 export하는 타입을 기준으로 TypeScript로 작성했기 때문에, 이 부분이 바뀌면 동작이 조용히 틀어지는 대신 빌드가 실패합니다.
여기서 말하는 “지원”
추측이 아니라 확인할 수 있는 범위
출시된 어댑터는 모두 지원하는 호스트 버전 범위를 명시하고, CI에서 그 범위 양 끝 버전의 실제 호스트로 테스트합니다.
| 어댑터 | 지원 범위 | 검증 방법 |
|---|---|---|
| adapter-pino | pino ^10.0.0 | 캡처한 스트림에 기록하는 실제 pino 로거 |
| adapter-otel | @opentelemetry/sdk-trace-base ^2.0.0 | onEnd를 거치는 실제 span |
| Python logging | CPython >=3.10 | 필터를 붙인 실제 로거 |
| Python otel | opentelemetry-sdk <2,>=1.16.0 | 실제 tracer provider를 거치는 실제 span |
선언한 범위 밖의 pino 메이저 버전은 일부러 지원한다고 적지 않습니다. 동작할 수도 있지만 테스트하지 않았기 때문입니다. 코어도 탐지기에 같은 원칙을 적용합니다.
솔직하게