macOS security 명령어로 키체인 다루기
개발하다 보면 API 키, 데이터베이스 비밀번호, 토큰 같은 민감한 정보를 다룰 일이 많은데요.
이런 값들을 .env 파일이나 설정 파일에 평문으로 저장해두면 실수로 Git에 커밋하거나 다른 사람에게 노출될 위험이 있습니다.
macOS에는 이런 민감한 정보를 안전하게 보관할 수 있는 키체인(Keychain)이라는 시스템이 내장되어 있는데요.
보통은 키체인 접근(Keychain Access) 앱을 통해 GUI로 사용하지만, 터미널에서 security 명령어를 사용하면 키체인을 훨씬 효율적으로 다룰 수 있습니다.
이번 글에서는 security 명령어의 핵심 기능을 실용적인 예제와 함께 살펴보겠습니다.
security 명령어란?
security는 macOS에 기본으로 설치되어 있는 CLI 도구로, 키체인과 보안 프레임워크에 접근할 수 있게 해줍니다.
별도의 설치 없이 바로 사용할 수 있고, 매뉴얼도 확인할 수 있습니다.
man security
사용 가능한 하위 명령어 목록을 보려면 아무 인자 없이 실행하면 됩니다.
security
usage: security [-h] [-i] [-l] [-p prompt] [-q] [command] [opt ...]
-i Run in interactive mode.
-l Run /usr/bin/leaks -nocontext before exiting.
-p Set the prompt to "prompt" (implies -i).
-q Will make most output quiet.
...
꽤 많은 하위 명령어가 나오는데요, 이 중에서 실무에서 자주 쓰는 것들을 중심으로 알아보겠습니다.
키체인 목록 확인
macOS는 여러 개의 키체인을 동시에 관리합니다.
현재 검색 경로에 등록된 키체인 목록을 확인하려면 list-keychains 명령어를 사용합니다.
security list-keychains
"/Users/dale/Library/Keychains/login.keychain-db"
"/Library/Keychains/System.keychain"
보통 두 가지 키체인이 보이는데요.
login.keychain-db는 현재 사용자 전용 키체인으로, 로그인할 때 자동으로 잠금 해제됩니다.
System.keychain은 시스템 전체에서 사용하는 키체인으로, 수정하려면 관리자 권한이 필요합니다.
기본 키체인이 어떤 것인지 확인하려면 이렇게 합니다.
security default-keychain
"/Users/dale/Library/Keychains/login.keychain-db"
대부분의 경우 login.keychain-db가 기본 키체인으로 설정되어 있습니다.
비밀번호 저장하기
security 명령어의 가장 유용한 기능 중 하나가 바로 비밀번호 저장과 조회인데요.
비밀번호를 저장할 때는 크게 두 가지 방식이 있습니다.
첫 번째는 add-generic-password로, 앱이나 서비스 이름을 기준으로 비밀번호를 저장합니다.
security add-generic-password \
-s "my-api-key" \
-a "dale" \
-w "sk-1234567890abcdef"
여기서 -s는 서비스(service) 이름, -a는 계정(account) 이름, -w는 저장할 비밀번호(password)입니다.
두 번째는 add-internet-password로, URL이나 서버 주소를 기준으로 비밀번호를 저장합니다.
security add-internet-password \
-s "api.example.com" \
-a "dale@example.com" \
-w "my-secret-password" \
-r "htps" \
-p "/"
-s는 서버(server) 주소, -r은 프로토콜(protocol), -p는 경로(path)입니다.
프로토콜은 4글자 코드를 사용하는데, HTTPS는 htps, HTTP는 http로 지정합니다.
💡 이미 같은 서비스/계정 조합으로 저장된 항목이 있으면 오류가 발생합니다. 기존 항목을 업데이트하려면
-U플래그를 추가하면 됩니다.
security add-generic-password \
-s "my-api-key" \
-a "dale" \
-w "new-secret-value" \
-U
비밀번호 조회하기
저장한 비밀번호를 가져오려면 find-generic-password를 사용합니다.
security find-generic-password -s "my-api-key" -a "dale"
keychain: "/Users/dale/Library/Keychains/login.keychain-db"
version: 512
class: "genp"
attributes:
...
"svce"<blob>="my-api-key"
"acct"<blob>="dale"
...
이렇게 하면 항목의 메타데이터가 출력되는데요, 비밀번호 값 자체는 보이지 않습니다.
비밀번호 값만 깔끔하게 가져오려면 -w 플래그를 추가합니다.
security find-generic-password -s "my-api-key" -a "dale" -w
sk-1234567890abcdef
이 기능이 특히 유용한 건 셸 스크립트에서 환경변수로 활용할 때인데요.
export API_KEY=$(security find-generic-password -s "my-api-key" -a "dale" -w)
echo "API_KEY가 설정되었습니다."
이렇게 하면 비밀번호를 파일에 저장하지 않고도 스크립트에서 안전하게 사용할 수 있습니다.
인터넷 비밀번호를 조회할 때는 find-internet-password를 사용합니다.
security find-internet-password -s "api.example.com" -a "dale@example.com" -w
비밀번호 삭제하기
더 이상 필요하지 않은 비밀번호는 delete-generic-password로 삭제할 수 있습니다.
security delete-generic-password -s "my-api-key" -a "dale"
password has been deleted.
인터넷 비밀번호를 삭제할 때는 delete-internet-password를 사용합니다.
security delete-internet-password -s "api.example.com" -a "dale@example.com"
키체인 잠금과 해제
키체인은 잠금 상태일 때 비밀번호를 읽을 수 없습니다. 보안이 중요한 상황에서 자리를 비울 때 키체인을 수동으로 잠글 수 있는데요.
security lock-keychain
이렇게 하면 기본 키체인(login.keychain-db)이 잠기고, 이후 비밀번호를 조회하려고 하면 시스템이 잠금 해제 비밀번호를 묻습니다.
특정 키체인을 잠그려면 경로를 지정합니다.
security lock-keychain ~/Library/Keychains/login.keychain-db
잠금을 해제할 때는 unlock-keychain을 사용합니다.
security unlock-keychain
비밀번호를 입력하라는 프롬프트가 나타나는데요, -p 옵션으로 비밀번호를 직접 전달할 수도 있습니다.
다만 이 방법은 셸 히스토리에 비밀번호가 남을 수 있어서 주의가 필요합니다.
키체인 생성과 삭제
프로젝트별로 별도의 키체인을 만들어서 비밀번호를 관리하고 싶을 때가 있는데요.
create-keychain으로 새로운 키체인을 만들 수 있습니다.
security create-keychain -p "keychain-password" ~/Library/Keychains/my-project.keychain-db
-p 뒤에 오는 값은 이 키체인의 잠금 해제 비밀번호입니다.
새로 만든 키체인을 검색 경로에 추가해야 security 명령어로 접근할 수 있습니다.
security list-keychains -s \
~/Library/Keychains/login.keychain-db \
~/Library/Keychains/my-project.keychain-db
이제 이 키체인에 비밀번호를 저장할 수 있습니다.
security add-generic-password \
-s "project-db-password" \
-a "admin" \
-w "super-secret" \
~/Library/Keychains/my-project.keychain-db
키체인이 더 이상 필요 없어지면 삭제합니다.
security delete-keychain ~/Library/Keychains/my-project.keychain-db
인증서 관리
security 명령어로 인증서도 다룰 수 있는데요.
키체인에 저장된 인증서 목록을 확인하려면 find-certificate를 사용합니다.
security find-certificate -a
모든 인증서가 쏟아져 나와서 좀 당황스러울 수 있는데요 😅 특정 이름으로 필터링하면 원하는 인증서만 찾을 수 있습니다.
security find-certificate -c "Apple" -a
-c 옵션은 인증서의 Common Name(일반 이름)을 기준으로 검색합니다.
-a는 일치하는 모든 인증서를 출력하라는 뜻인데, 빼면 첫 번째 일치 항목만 나옵니다.
인증서의 상세 정보를 PEM 형식으로 보고 싶다면 -p 플래그를 추가합니다.
security find-certificate -c "Apple Development" -p
-----BEGIN CERTIFICATE-----
MIIFkzCCBHugAwIBAgIIE5N...
-----END CERTIFICATE-----
외부에서 받은 인증서를 키체인에 추가할 때는 add-certificates 또는 import를 사용합니다.
security add-certificates my-cert.cer
PKCS12(.p12) 형식의 인증서를 가져올 때는 import가 더 적합합니다.
security import my-cert.p12 -k ~/Library/Keychains/login.keychain-db -P "인증서비밀번호"
-k로 저장할 키체인을, -P로 PKCS12 파일의 비밀번호를 지정합니다.
인증서의 신뢰 설정을 변경할 수도 있는데요.
security add-trusted-cert -d -r trustRoot -k ~/Library/Keychains/login.keychain-db my-ca.cer
-d는 관리자 인증서 저장소에 추가하겠다는 뜻이고, -r trustRoot는 루트 인증서로 신뢰하겠다는 의미입니다.
로컬 개발 환경에서 자체 서명 인증서를 사용할 때 유용합니다.
자동화 스크립트 활용
security 명령어의 진가는 자동화 스크립트에서 발휘됩니다.
몇 가지 실용적인 활용 예를 살펴볼게요.
먼저 .zshrc나 .bashrc에서 환경변수를 키체인으로부터 불러오는 방법입니다.
# 키체인에서 API 키 로드
export OPENAI_API_KEY=$(security find-generic-password -s "openai-api-key" -a "$USER" -w 2>/dev/null)
export AWS_SECRET_ACCESS_KEY=$(security find-generic-password -s "aws-secret-key" -a "$USER" -w 2>/dev/null)
2>/dev/null을 붙이면 항목이 없을 때 에러 메시지를 숨길 수 있습니다.
비밀번호를 저장하고 조회하는 과정을 편하게 만드는 셸 함수도 만들어볼 수 있습니다.
# 키체인에 비밀번호 저장
kc-set() {
security add-generic-password -s "$1" -a "$USER" -w "$2" -U
echo "✅ '$1' 저장 완료"
}
# 키체인에서 비밀번호 조회
kc-get() {
security find-generic-password -s "$1" -a "$USER" -w 2>/dev/null
}
# 키체인에서 비밀번호 삭제
kc-del() {
security delete-generic-password -s "$1" -a "$USER" >/dev/null 2>&1
echo "🗑️ '$1' 삭제 완료"
}
이렇게 설정하면 아주 간단하게 비밀번호를 관리할 수 있습니다.
kc-set "github-token" "ghp_xxxxxxxxxxxx"
kc-get "github-token"
kc-del "github-token"
CI/CD 환경에서도 유용한데요.
macOS 기반 CI(예: GitHub Actions의 macos-runner)에서 코드 서명용 인증서를 설정하는 스크립트를 작성할 수 있습니다.
#!/bin/bash
# 임시 키체인 생성
KEYCHAIN_PATH="$HOME/Library/Keychains/build.keychain-db"
KEYCHAIN_PASSWORD="temporary-password"
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security set-keychain-settings -lut 3600 "$KEYCHAIN_PATH"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
# 인증서 가져오기
echo "$CERTIFICATE_BASE64" | base64 --decode > /tmp/certificate.p12
security import /tmp/certificate.p12 \
-k "$KEYCHAIN_PATH" \
-P "$CERTIFICATE_PASSWORD" \
-T /usr/bin/codesign
# 키체인 검색 경로에 추가
security list-keychains -s "$KEYCHAIN_PATH" login.keychain-db
security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
# 임시 파일 정리
rm /tmp/certificate.p12
set-keychain-settings의 -lut 3600은 키체인이 1시간 후 자동으로 잠기도록 설정하는 것이고, set-key-partition-list는 codesign이 키체인에 접근할 수 있도록 권한을 부여합니다.
키체인 덤프와 디버깅
키체인에 어떤 항목들이 저장되어 있는지 전체적으로 파악하고 싶을 때는 dump-keychain을 사용합니다.
security dump-keychain
비밀번호 값은 포함되지 않고 메타데이터만 출력되니 안심하셔도 됩니다.
비밀번호까지 함께 보려면 -d 플래그를 추가하면 되는데, 각 항목마다 접근 승인을 요구합니다.
특정 키체인만 덤프할 수도 있습니다.
security dump-keychain ~/Library/Keychains/login.keychain-db
문제가 발생했을 때 키체인 상태를 확인하는 데 유용한 명령어도 있습니다.
security show-keychain-info ~/Library/Keychains/login.keychain-db
Keychain "/Users/dale/Library/Keychains/login.keychain-db" lock-on-sleep timeout=300s
키체인의 잠금 정책(절전 시 잠금, 타임아웃 시간 등)을 확인할 수 있습니다.
주의사항
security 명령어를 사용할 때 알아두면 좋은 점들이 있습니다.
우선 셸 히스토리에 비밀번호가 남을 수 있습니다.
-w 옵션으로 비밀번호를 직접 전달하면 히스토리에 기록되는데요.
이를 방지하려면 명령어 앞에 공백을 넣거나(대부분의 셸에서 히스토리에 기록되지 않음), 파이프로 전달하는 방법이 있습니다.
# 방법 1: 명령어 앞 공백 (HISTCONTROL=ignorespace 설정 필요)
security add-generic-password -s "my-secret" -a "$USER" -w "password123" -U
# 방법 2: read로 입력 받기
read -s -p "비밀번호: " PW && security add-generic-password -s "my-secret" -a "$USER" -w "$PW" -U
그리고 접근 제어(ACL)도 신경 써야 합니다.
기본적으로 키체인 항목을 만든 앱만 해당 항목에 접근할 수 있는데요.
security 명령어로 만든 항목은 security 명령어로만 비밀번호를 조회할 수 있습니다.
다른 앱에서도 접근할 수 있게 하려면 키체인 접근 앱에서 해당 항목의 접근 제어 설정을 수정해야 합니다.
마지막으로, security 명령어는 macOS에서만 동작합니다.
크로스 플랫폼 스크립트를 작성할 때는 OS를 확인하는 로직을 넣어야 합니다.
case "$(uname -s)" in
Darwin)
API_KEY=$(security find-generic-password -s "api-key" -a "$USER" -w 2>/dev/null)
;;
Linux)
API_KEY=$(secret-tool lookup service "api-key" 2>/dev/null)
;;
esac
Linux에서는 secret-tool이나 pass 같은 도구가 비슷한 역할을 합니다.
마치며
macOS의 security 명령어를 사용하면 키체인을 터미널에서 자유자재로 다룰 수 있습니다.
API 키나 비밀번호를 .env 파일에 평문으로 저장하는 대신 키체인에 보관하면 보안 사고의 위험을 크게 줄일 수 있고, 셸 스크립트와 결합하면 자동화도 간편해집니다.
특히 앞서 살펴본 kc-set, kc-get, kc-del 같은 셸 함수를 설정해두면 일상적인 개발 워크플로우에서 매우 편리하게 사용할 수 있으니 한번 시도해 보시기 바랍니다.
security 명령어의 전체 옵션이 궁금하시다면 Apple의 공식 문서를 참고하시면 됩니다.
macOS를 개발 환경으로 활용하는 더 많은 팁이 궁금하시다면 Homebrew 완벽 가이드도 읽어보세요.
This work is licensed under
CC BY 4.0