API 키
고친 사람 github-actions[bot]
API 키는 바깥 서비스를 부르는 프로그램이 어느 쪽인지 그 서비스에 알려 줍니다. 서비스는 부르는 쪽마다 다른 문자열을 미리 나눠 줍니다. 부르는 쪽은 요청을 보낼 때마다 그 문자열을 함께 실어 보냅니다. 서비스는 그 문자열을 보고 누가 얼마나 쓰는지 셉니다.
쉽고 빠른 이해
API 키는 서비스를 부르는 프로그램이 어느 쪽인지 서비스에 알려 줍니다. 결제 서비스에 가입하면 sk_test_ 로 시작하는 키를 받아 요청마다 함께 보냅니다.
이게 없으면 서비스는 들어온 요청이 어느 쪽 것인지 모릅니다. 누가 얼마나 썼는지 셀 수 없습니다. 마구 긁어 가는 쪽만 골라 막을 수도 없습니다.
- 서비스가 부르는 쪽마다 다른 키를 만들어 건넵니다
- 부르는 쪽이 요청 헤더나 주소에 그 키를 실어 보냅니다
- 서비스가 키로 어느 쪽인지 찾은 뒤 사용량과 허락된 일을 가립니다
대가는 키 하나가 곧 출입증이라는 것입니다. 새어 나가면 주운 쪽이 키를 받은 쪽인 척 부를 수 있습니다. 키는 부르는 쪽을 알아볼 뿐 그 뒤의 사람 한 명까지 가리지는 않습니다.
민감한 자원은 키 하나에만 맡기지 않습니다. 접근을 막는 일에는 다른 장치를 함께 씁니다.
상세
헬스장은 회원마다 출입 카드를 한 장씩 내줍니다. 입구에서 카드를 찍으면 문이 열립니다. 그 회원이 이번 달에 몇 번 왔는지도 함께 기록됩니다.
API(Application Programming Interface, 응용 프로그램 인터페이스)는 한 프로그램이 다른 프로그램의 기능을 불러 쓰는 통로입니다. API 키는 서비스가 API 를 부르는 쪽마다 미리 나눠 주는 문자열입니다. 지도나 결제 서비스에 가입하면 관리 화면에서 받는 긴 영문·숫자 뭉치가 그런 문자열입니다.
부르는 쪽은 요청을 보낼 때마다 이 문자열을 함께 실어 보냅니다. 서비스는 그것을 보고 요청이 어느 쪽에서 왔는지 알아봅니다. 앞의 출입 카드처럼 요청마다 찍는 값입니다.
키가 알아보는 것은 그 키를 받아 간 쪽, 곧 부르는 쪽입니다. 그 뒤에서 일을 시킨 사람 한 명까지 알아보는지는 아래 「경계」 절이 판정합니다.
키를 싣는 통로
이 소절은 요청의 어디에 키를 싣는지 다룹니다. API 를 설명하는 문서에 키의 통로로 적을 수 있는 것은 셋입니다.
| 통로 | 무엇인가 | 요청에 실린 꼴 |
|---|---|---|
| 헤더 | 요청 본문과 따로 붙는 이름과 값의 쌍 | api_key: <키> |
| 쿼리 문자열 | 주소 끝의 ? 뒤에 붙는 이름과 값 |
...?api_key=<키> |
| 쿠키 | 부르는 쪽이 저장해 두었다가 요청마다 함께 보내는 값 | Cookie: api_key=<키> |
표의 api_key 는 이름의 한 예입니다. 어느 통로에 싣든 그 이름은 서비스가 정합니다. 헤더 이름을
x-api-key 로 정한 서비스도 있습니다.
요청 본문도 통로가 됩니다. 본문을 싣는 요청이면 키 같은 민감한 값을 본문에 담아 보내기도 합니다. 주소에 실은 키는 웹 서버 로그에 남을 수 있습니다. 그 문제는 아래 「운영」 절에서 다룹니다.
서버가 키로 하는 검사
키가 실린 요청 하나가 서버에 닿은 뒤를 따라갑니다. 서버는 요청을 처리하기 전에 키부터 봅니다. 먼저 키 목록에서 그 키를 받아 간 쪽을 찾습니다. 맞는 키가 없으면 거기서 거절합니다.
찾은 뒤에는 두 가지를 가립니다. 그쪽 몫의 사용량이 한도 안인지, 요청한 일이 그쪽에 허락된 일인지입니다. 하나라도 걸리면 거절합니다.
sequenceDiagram
participant 부름 as 부르는 쪽
participant 서버
participant 목록 as 키 목록
부름->>서버: 요청 · 키를 실어 보낸다
서버->>목록: 이 키를 받아 간 쪽은 누구인가
Note over 서버,목록: 맞는 키가 없으면 여기서 거절한다
목록-->>서버: 부르는 쪽 · 한도 · 허락된 일
서버->>서버: 사용량이 한도 안인지, 허락된 일인지 가린다
Note over 서버: 하나라도 걸리면 여기서 거절한다
서버-->>부름: 처리한 결과
검사를 다 지난 요청만 처리로 넘어갑니다.
권장되는 대응은 둘입니다. 너무 빨리 들어오는 요청에는 HTTP(HyperText Transfer Protocol) 응답 코드 429 Too Many Requests 를 돌려줍니다. 이용 약속을 어긴 쪽의 키는 거둬들여 막습니다.
이용 약속은 서비스가 키를 내줄 때 정해 둔 사용 조건입니다. 거둬들인다는 것은 그 키 값을 더는 못 쓰게 만든다는 뜻입니다.
배경
아무 장치 없이 열어 둔 API 하나를 떠올려 봅니다. 이 절은 그 API 에서 무엇이 곤란해 키가 생겼는지 따라갑니다.
접근을 막는 장치가 없는 공개 API 는 누구든 부를 수 있습니다. 누가 요청을 쏟아부어 데이터를 대량으로 긁어 가도 서비스는 그쪽을 가려낼 방법이 없습니다. 그런 API 는 긁혀 갈 위험을 안고 있습니다. 대역폭과 계산 비용이 지나치게 불어난 청구서로 이어질 수 있습니다.
막으려면 부르는 쪽을 가를 수 있어야 합니다. 부르는 쪽마다 다른 값을 나눠 줍니다. 요청마다 그 값을 실어 오게 하면 이 위험을 줄일 수 있습니다.
같은 장치는 API 를 돈을 받고 파는 데도 자주 쓰입니다. 이때는 많이 부르는 쪽을 무조건 막지 않습니다. 부르는 쪽이 산 이용 요금제가 허락하는 만큼 쓰게 해 줍니다.
이렇게 나눠 주는 값을 API 키라고 부릅니다. API 키는 서비스 거부 공격, 곧 요청을 쏟아부어 서비스를 멈추게 하는 공격의 피해를 줄일 수 있습니다. 다만 바깥 프로그램에 나눠 준 키는 비교적 쉽게 남의 손에 넘어갑니다. 민감하거나 값어치가 큰 자원을 API 키 하나에만 기대어 지키지 않도록 권합니다.
예시
분야가 다른 두 서비스에서 API 키가 어떤 꼴로 오가는지 견줍니다. 결제 서비스 Stripe 와, AWS(Amazon Web Services)의 API 관문 서비스 Amazon API Gateway 입니다. API 관문은 여러 API 앞에 서서 요청을 먼저 받아 검사한 뒤 뒤로 넘기는 서버입니다. 끝에 API 를 설명하는 문서에 키가 적히는 꼴을 하나 붙입니다.
Stripe 의 키 종류
Stripe 는 계정을 만들면 키 세 종류를 만들어 줍니다. 접두어만 보고 어느 키인지 알 수 있습니다.
| 종류 | 접두어 | 밖에 드러내도 되나 | 할 수 있는 일 |
|---|---|---|---|
| 공개 키 (publishable) | pk_ |
된다 | 계정을 알아보고, 결제 정보를 받아 결제에 쓸 객체를 만든다. 결제를 일으키거나 계정 데이터를 읽는 민감한 일은 못 한다 |
| 제한 키 (restricted) | rk_ |
안 된다 | 만든 쪽이 정한 권한만 쓴다 |
| 비밀 키 (secret) | sk_ |
안 된다 | 모든 Stripe API 를 제한 없이 쓴다 |
공개 키는 브라우저에서 도는 코드나 배포하는 애플리케이션에 넣어도 됩니다. 비밀 키는 권한을 줄일 수 없습니다. Stripe 는 새로 쓰는 곳에 비밀 키를 권하지 않습니다. 이미 쓰는 곳도 제한 키로 옮기기를 권합니다.
이 셋 말고 조직 단위로 동작하는 조직 키 sk_org_ 도 있습니다.
접두어 뒤에는 모드가 붙습니다. 시험용 샌드박스의 키는 pk_test_ · rk_test_ · sk_test_ 로
시작합니다. 실거래 키는 pk_live_ · rk_live_ · sk_live_ 로 시작합니다.
모드마다 키가 따로 있습니다. 한 모드에서 만든 객체는 다른 모드에서 접근할 수 없습니다.
Amazon API Gateway 의 키와 사용량 계획
API Gateway 에서 키는 이름과 값을 가집니다. 이름은 1024자를 넘을 수 없습니다. 값은 20자에서
128자 사이의 영숫자 문자열입니다. apikey1234abcdefghij0123456789 같은 꼴입니다.
값은 겹칠 수 없습니다. 이름이 달라도 값이 같으면 같은 키로 봅니다.
키를 묶는 단위는 사용량 계획(usage plan)입니다. 사용량 계획은 배포된 API 단계와 메서드에 누가 닿을 수 있는지 정합니다. 단계(stage)는 API 를 배포해 둔 단위입니다. 부르는 쪽은 키로 알아봅니다.
사용량 계획에는 한도를 걸 수도 있습니다. 걸 수 있는 한도는 둘입니다. 스로틀링(throttling)은 요청이 너무 빨리 들어올 때 그 속도를 조절하는 일입니다. 쿼터(quota)는 정해진 기간 동안 보낼 수 있는 요청 수의 상한입니다.
| 한도 | 정하는 것 |
|---|---|
| 스로틀링 한도 | 요청 조절을 시작할 목표 요청 속도. API 전체나 메서드마다 정한다 |
| 쿼터 한도 | 정해진 기간 안에 한 키로 보낼 수 있는 요청 수의 목표 최대치 |
두 한도는 키마다 셉니다. 한 키가 계획 안의 여러 단계에 보낸 요청을 모두 합쳐 셉니다. 아래 그림의 키 A 가 두 단계에 보낸 요청은 한 줄로 모여 한도에 걸립니다.
flowchart TD
subgraph 계획["사용량 계획"]
L["한도 · 스로틀링 · 쿼터"]
KA["키 A"]
KB["키 B"]
end
KA --> S1["API 1 의 단계"]
KA --> S2["API 2 의 단계"]
KB --> S1
KB --> S2
아래는 키를 실은 요청 하나입니다.
GET /testStage/pets?type=dog&page=1 HTTP/1.1
x-api-key: Hiorr45VR...c4GJc
Content-Type: application/x-www-form-urlencoded
Host: xbvxlpijch.execute-api.ap-southeast-1.amazonaws.com
키는 x-api-key 헤더에 실렸습니다. 관문은 이 키를 읽어 사용량 계획에 든 키와 대조합니다. 맞으면
계획의 한도대로 요청을 조절해 뒤로 넘깁니다. 키가 없거나 틀리면 403 Forbidden 을 돌려줍니다.
메서드가 키를 요구하도록 설정하지 않았으면, 헤더에 키를 맞게 실었든 아니든 200 OK 가 돌아올 가능성이 큽니다. 사용량 계획의 한도도 걸리지 않습니다.
flowchart TD
A["요청이 관문에 닿는다"] --> B{"이 메서드가 키를 요구하나"}
B -->|아니다| C["키와 상관없이 200 OK 일 가능성이 크다 · 한도도 안 걸린다"]
B -->|그렇다| D{"키가 사용량 계획의 키와 맞나"}
D -->|없거나 안 맞다| E["403 Forbidden"]
D -->|맞다| F["계획의 한도대로 조절해 뒤로 넘긴다"]
OpenAPI 문서에 적는 꼴
OpenAPI 는 API 를 기계가 읽는 문서로 적는 표준입니다. 이 문서에서 API 키는 보안 방식의 한 종류로 적힙니다.
type: apiKey
name: api_key
in: header
type 은 보안 방식의 종류입니다. apiKey · http · mutualTLS · oauth2 · openIdConnect
다섯 가운데 하나를 씁니다.
in 은 키를 싣는 통로입니다. query · header · cookie 셋 가운데 하나를 씁니다. name 은 그
헤더나 쿼리 매개변수, 쿠키의 이름입니다. 상세 절의 표에 든 세 통로가 이 셋입니다.
경계
이 절은 Google Cloud·Amazon API Gateway·Stripe 세 서비스의 API 키를 놓고 한 물음을 판정합니다. API 키는 그 키를 쓰는 주체를 인증하나.
낱말부터 정합니다. 인증은 요청을 보낸 쪽이 누구인지 확인하는 일입니다. 인가는 그쪽이 그 일을 해도 되는지 가리는 일입니다.
주체(principal)는 권한 검사를 받는 이름입니다. 사람 한 명이나 서비스 계정이 그 예입니다. 서비스 계정은 사람이 아닌 프로그램에게 내주는 주체입니다.
IAM(Identity and Access Management, 권한 관리 장치)은 주체마다 할 수 있는 일을 검사하는 장치입니다. Google Cloud 와 AWS 가 같은 이름의 장치를 둡니다.
세 서비스는 키가 알아보는 단위를 저마다 다른 이름으로 부릅니다. 아래 표의 가운데 칸이 그 이름입니다.
| 서비스 | 키가 알아보는 것 | 인증에 대한 말 |
|---|---|---|
| Google Cloud 표준 API 키 | 프로젝트. 요금과 쿼터를 매기는 묶음이다 | 주체를 알아보지 않는다. 권한 검사를 IAM 으로 할 수 없다 |
| Amazon API Gateway | 사용량 계획 안의 부르는 쪽 | 접근을 통제하는 인증·인가 수단으로 쓰지 말라 |
| Stripe | 연동(integration). Stripe 를 부르도록 짠 코드다. 공개 키는 계정도 알아본다 | 연동에서 온 요청을 인증하고, 그 연동이 닿을 자원을 정한다 |
판정은 아닙니다. 보통의 API 키가 알아보는 것은 표의 프로젝트·부르는 쪽·연동·계정입니다. 권한 검사를 받는 주체가 아닙니다.
표의 계정은 Stripe 에 가입할 때 만드는 계정입니다. 이름이 비슷하지만 앞에서 주체의 예로 든 서비스 계정과는 다른 것입니다.
세 서비스가 「인증」이라는 낱말을 다르게 씁니다. Stripe 는 키로 요청을 인증한다고 말합니다. 그래도 인증되는 대상은 연동입니다. 키가 사람 한 명을 알아보지 않는다는 점에서는 셋이 같습니다.
Google Cloud 의 표준 키는 요청을 프로젝트에 묶을 뿐 주체를 알아보지 않습니다. 주체가 없으니 IAM 으로 그 요청이 허락된 일인지 검사할 수 없습니다.
Amazon API Gateway 에서는 사용량 계획 하나에 API 가 여럿 묶이면 그중 한 API 에 유효한 키로 계획 안의 모든 API 에 닿습니다. 「예시」 절 그림에서 키 A 가 두 API 의 단계에 다 닿는 것과 같은 모양입니다. 접근을 막는 일은 키 대신 아래 셋이 맡습니다.
| 장치 | 무엇인가 |
|---|---|
| IAM 역할 | IAM 에서 권한을 묶어 맡기는 이름 |
| Lambda 권한 부여자(authorizer) | 요청을 받아 권한 판정 응답을 돌려주는 함수 |
| Amazon Cognito 사용자 풀 | Amazon Cognito 에 등록한 사용자의 묶음 |
예외가 하나 있습니다. Google Cloud 의 인가 키(authorization key)는 서비스 계정에 묶인 API 키입니다. 이 키로 부르면 묶인 서비스 계정이 부른 것처럼 처리됩니다.
액세스 토큰은 주체를 확인한 뒤 그 주체에게 내주는 문자열입니다. 인가 키는 오래 사는 액세스 토큰과 비슷하게 동작합니다. Google Cloud 는 자원을 만들거나 관리하는 API 에서는 이 키를 운영 환경에 쓰지 말라고 안내합니다. 처음 둘러볼 때만 쓰라는 것입니다.
운영
이 절은 Stripe·Google Cloud·Amazon API Gateway·GitHub 에서 키를 굴리는 쪽이 만지는 설정과 지켜볼 지표를 다룹니다. 축은 넷입니다. 한 번만 보여 주는 키, 회전할 때 겹치는 기간, 키를 묶는 제한, 새어 나간 키를 찾는 장치입니다.
네 축에 두루 나오는 낱말이 회전입니다. 키 회전은 쓰던 키를 새 키로 바꾸는 일입니다. 옛 키는 거둬들입니다. 대신할 새 키는 바로 쓸 수 있습니다.
한 번만 보여 주는 키
Stripe 는 실거래 모드에서 비밀 키를 만들면 저장하기 전에 한 번만 보여 줍니다. 그 뒤로는 다시 볼 수 없습니다. 잃어버린 키는 Stripe 도 되살리지 못합니다. 잃었으면 그 키를 회전합니다. 아니면 지운 뒤 새 키를 만듭니다.
예외가 있습니다. 실거래 모드에서도 Stripe 가 만들어 준 키는 다시 볼 수 있습니다. 기본 비밀 키나 예약해 둔 회전이 만든 키가 그렇습니다.
샌드박스 모드에서는 제한 키와 비밀 키를 포함해 모든 키를 언제든 볼 수 있습니다. 공개 키는 민감하지 않아 처음부터 보입니다.
Google Cloud 의 키에는 문자열과 ID(identifier, 식별자)가 따로 있습니다. API 를 부를 때는 언제나
AIzaSyDaGmWKa4JsXZ-HjGw7ISLn_3namBGewQe 같은 키 문자열을 씁니다. 키 ID 는 관리 도구가 키를
가리킬 때 씁니다. API 를 부르는 데는 못 씁니다.
회전과 겹치는 기간
주기적으로 회전하면 새어 나간 키의 피해를 줄일 수 있습니다. Stripe 는 키를 잃어 되살릴 수 없을 때, 키가 새어 나갔을 때, 키를 아는 팀원이 떠나거나 역할이 바뀌었을 때, 정해 둔 주기가 됐을 때를 회전 시점으로 듭니다. 정해 둔 시간이 지나면 회전하도록 예약할 수도 있습니다.
Stripe 대시보드에서 회전하면 옛 키와 새 키가 최대 7일 동안 함께 동작합니다. 만료일은
Expiration 목록에서 고릅니다. Now 를 고르면 옛 키가 바로 지워집니다. 7일보다 길게 필요하면
새 키를 손으로 만들어 옮긴 뒤 옛 키를 만료시킵니다.
stateDiagram-v2
[*] --> 둘다동작 : 대시보드에서 회전
둘다동작 --> 새키만 : 고른 만료일이 된다 · 최대 7일
[*] --> 새키만 : 만료를 Now 로 고른다
새키만 --> [*]
둘다동작 : 옛 키와 새 키가 함께 동작한다
새키만 : 옛 키가 지워지고 새 키만 동작한다
지켜볼 지표는 옛 키의 요청량입니다. 옛 키가 만료되기 전에 그 키의 요청 기록을 확인합니다. Stripe 는 요청량이 몇 시간이나 며칠 동안 0 에 머문 뒤에 만료시키기를 권합니다.
Google Cloud 에서 회전할 때는 옛 키와 같은 제한을 건 새 키를 만듭니다. 제한은 바로 아래 소절이 다룹니다. 애플리케이션을 전부 새 키로 바꾼 뒤 옛 키를 지웁니다.
너무 일찍 지웠으면 지운 지 30일 안에 되살릴 수 있습니다. 30일이 지나면 되살릴 수 없습니다.
stateDiagram-v2
[*] --> 옛키동작 : 새 키를 만든다
옛키동작 --> 지워짐 : 애플리케이션을 다 바꾼 뒤 지운다
지워짐 --> 옛키동작 : 30일 안에 되살린다
지워짐 --> 되살릴수없음 : 30일이 지난다
되살릴수없음 --> [*]
옛키동작 : 옛 키가 아직 동작한다
지워짐 : 옛 키를 지웠다
되살릴수없음 : 옛 키를 되살릴 수 없다
키를 묶는 제한
제한은 새어 나간 키로 남이 할 수 있는 일을 줄입니다. Google Cloud 는 제한 없는 키를 안전하지 않다고 봅니다. 제한은 두 갈래입니다. Google Cloud 는 둘 다 걸기를 권합니다.
| 제한 | 묶는 대상 | 걸지 않았을 때 |
|---|---|---|
| API 제한 | 키로 부를 수 있는 API 목록 | Google Cloud 가 만든 키를 받는 모든 API 에 쓸 수 있다 |
| 애플리케이션 제한 | 키를 쓸 수 있는 웹사이트 · IP(Internet Protocol) 주소 · Android 앱 · iOS 앱 | 어디서든 쓸 수 있다 |
콘솔이나 명령줄 도구로 키를 만들면 API 제한을 하나 이상 걸어야 합니다. REST(Representational State Transfer) API 로 직접 만들면 따로 지정하지 않는 한 제한 없는 키가 나옵니다. 애플리케이션 제한은 한 번에 한 종류만 겁니다.
웹사이트 제한은 HTTP 리퍼러(referrer)로 겁니다. 리퍼러는 요청이 어느 사이트에서 왔는지 적힌
값입니다. https://example.com 을 넣으면 그 사이트에서 온 호출만 그 키를 쓸 수 있습니다. IP 주소
제한은 서비스 계정에 묶인 인가 키에 걸 수 있는 유일한 제한입니다.
Stripe 는 키에 접근 정책을 붙입니다. IP 주소 정책은 IPv4 주소나 CIDR(Classless Inter-Domain Routing) 표기의 주소 범위로 묶습니다. 서버 IP 주소가 고정이면 이 정책을 씁니다.
고급 정책은 국가 · 흔한 위협 분류 · ASN(Autonomous System Number, 자율 시스템 번호)으로 묶습니다. ASN 은 한 사업자의 네트워크에 붙는 번호입니다. 서버 수를 그때그때 늘리고 줄이는 환경이면 클라우드 사업자의 ASN 과 국가로 열어 줄 수 있습니다.
정책 밖에서 온 요청은 막힙니다. Stripe 는 그 사실을 알려 줍니다. Stripe 는 실거래 모드의 모든 키에 접근 정책을 걸기를 권합니다.
Amazon API Gateway 의 사용량 계획 한도는 엄격한 상한이 아닙니다. 스로틀링과 쿼터는 최선 노력(best-effort)으로 걸립니다. 경우에 따라 부르는 쪽이 API 를 내놓은 쪽이 정한 쿼터를 넘을 수 있습니다.
AWS 는 비용을 다스리거나 접근을 막는 데 이 한도에 기대지 말라고 안내합니다. 대신 AWS Budgets 로 비용을 지켜보기를 고려하라고 합니다. WAF(Web Application Firewall, 웹 애플리케이션 방화벽)로 API 요청을 다루는 방법도 함께 듭니다.
새어 나간 키를 찾는 장치
이 소절은 키가 새는 길 셋과 새어 나간 키를 찾는 장치 하나를 다룹니다.
첫째 길은 주소입니다. 주소에 실은 키는 웹 서버 로그에 남을 수 있습니다. 키가 담긴 로그는 그 자체로 값어치 있는 표적이 됩니다. 비밀번호·보안 토큰처럼 API 키도 주소에 나오지 않게 해야 합니다.
본문을 싣는 요청이면 민감한 값을 본문이나 헤더로 보냅니다.
둘째 길은 헤더 기록입니다. Amazon API Gateway 에서는 부르는 쪽이 대개 키를 헤더에 실어 보냅니다. 그 헤더도 로그에 남을 수 있습니다.
API Gateway 의 키는 관문이 만들어 주기도 합니다. CSV(Comma-Separated Values, 쉼표로 가른 값) 파일로 가져온 키를 쓸 수도 있습니다. AWS 는 관문이 만든 키를 쓰라고 권합니다. 키 문자열 안에 다른 기밀 정보를 섞어 넣지도 말라고 합니다. 헤더가 로그에 남으면 키 문자열에 섞인 정보도 함께 남습니다.
셋째 길은 코드와 대화입니다. Stripe 에서 백엔드 밖에 드러내도 되는 키는 공개 키뿐입니다. 나머지 키를 지키는 일은 키를 받은 쪽의 몫입니다.
Stripe 는 민감한 키를 호스팅 플랫폼이 주는 비밀 저장소(secrets vault)에 두라고 권합니다. 그럴 수 없으면 환경 변수로 백엔드에 넘깁니다. 버전 관리에 올라가는 소스 코드나 설정 파일에는 키를 넣지 않습니다. 이메일이나 채팅처럼 암호화되지 않은 통로로 키를 주고받지도 않습니다.
GitHub 의 비밀 탐지(secret scanning)는 저장소의 모든 브랜치에 걸친 Git 이력 전체를 훑습니다. 코드에 박힌 API 키·비밀번호·토큰을 찾습니다. 새 비밀 종류가 더해지면 저장소를 주기적으로 다시 훑습니다. 공개 저장소에서는 무료로 자동으로 돕니다.
찾은 뒤에는 협력 서비스의 비밀인지에 따라 길이 갈립니다. 협력 서비스는 GitHub 와 손잡고 찾은 비밀을 확인하는 서비스 제공자입니다.
flowchart TD
A["키가 담긴 커밋이 저장소에 들어온다"] --> B["비밀 탐지가 모든 브랜치의 Git 이력을 훑는다"]
B --> C{"협력 서비스의 비밀인가"}
C -->|그렇다| D["그 서비스에 바로 알린다 · 저장소 경고에는 안 뜬다"]
D --> E["그 서비스가 키를 거둬들이는 식으로 조치할 수 있다"]
C -->|아니다| F["저장소의 보안 탭에 경고가 뜬다"]
F --> G["경고를 받은 쪽이 키를 바로 회전한다"]
저장소 경고에는 새어 나간 자격 증명의 내용이 함께 뜹니다. 특정 서비스에 안 묶인 일반 API 키까지 찾도록 범위를 넓힐 수도 있습니다.
경고를 받으면 그 키를 바로 회전합니다. Git 이력에서 키를 지우는 일은 시간이 많이 듭니다. 이미 키를 거둬들였다면 많은 경우 필요 없습니다.
관련 항목
API 키를 대신할 수 있는 다른 자격 증명
액세스 토큰 · 리프레시 토큰 · JWT · 베어러 토큰 · 세션 쿠키 · 클라이언트 인증서 · 상호 TLS · 사전 공유 키 · 비밀번호 인증 · 다요소 인증
API 키로 치지 않는 이웃 비밀 값
웹훅 · 서명 · 인가 키
API 키를 발급하고 검사하는 주체
API 게이트웨이 · 인가 서버 · 자원 서버 · 자원 소유자 · 클라이언트 · 서비스 계정 · 주체
API 키를 발급해 쓰는 서비스
Stripe · Amazon API Gateway · Google Cloud · GitHub
API 키 대신 접근과 비용을 다스리는 AWS 장치
IAM 역할 · Lambda 권한 부여자 · Amazon Cognito · AWS WAF · AWS Budgets
API 키를 코드 밖에 보관하는 수단
시크릿 관리 · 비밀 저장소 · 환경 변수 · 자격 증명 · 암호화 키
API 키의 수명을 다루는 작업
키 회전 · 무효화 · 만료 · 비밀 탐지 · 감사 로그
키를 받은 서버가 이어서 하는 검사
인증 · 인가 · 접근 제어 · 스코프 · 최소 권한 · IAM
API 키에 거는 사용량 한도
속도 제한 · 스로틀링 · 쿼터 · 사용량 계획 · HTTP 429 · HTTP 403
API 키를 쓸 수 있는 곳을 좁히는 조건
HTTP 리퍼러 · IP 주소 · CIDR · ASN · 웹 애플리케이션 방화벽
키를 실어 나르는 통신 요소
헤더 · 쿼리 문자열 · 쿠키 · 요청 본문 · TLS · HTTP 인증 · 엔드포인트 · URL
API 키가 새어 나가는 통로
API 키를 노리거나 API 키로 피해를 줄이는 공격
자격 증명 탈취 · 토큰 탈취 · 중간자 공격 · 재전송 공격 · 무차별 대입 공격 · 서비스 거부 공격 · 공격 표면
API 키가 놓이는 설계 개념
API · API 설계 · 보안 스킴 · REST · OAuth 2.0 · OpenAPI · OpenID Connect · 토큰
다른 이름: API key · api key · API 키 값