Kaggle 노트북(predict.ipynb) 관련
선생님 안녕하세요!
Kaggle 노트북(predict.ipynb) 관련해서 문의 드립니다.
강의에서와 같이 Supabase URL/Key를 Kaggle의 Secrets 기능에 등록했는데요, 막상 노트북이 실행될 때마다 Kaggle 웹사이트에서 소스를 열어보면 Secrets가 아니라 실제 키 값이 노트북 코드에 그대로 박혀서 올라가는 현상을 발견했습니다. 클로드 한테 확인했더니 아래와 같이 설명해주었는데요.
- app/services/ml_trigger_service.py의 push_kernel()이 Kaggle에 push할 때마다, predict.py 원본 코드를 읽어서 .env의 실제 SUPABASE_URL / SUPABASE_KEY(또는 SUPABASE_SERVICE_ROLE_KEY) 값을 노트북 첫 셀에 os.environ[...] = '실제값' 형태로 직접 주입한 뒤, 그렇게 만들어진 predict.ipynb를 push합니다.
- 코드 주석에 따르면, 이렇게 우회한 이유는 "Kaggle Secrets(UserSecretsClient)가 API(kaggle kernels push)로 만든 커널에서는 'Connection error'로 실패한다"는 걸 실측 확인했기 때문이라고 되어 있습니다. 즉 Kaggle 웹 UI에서 직접 만든 커널이 아니라 API로 push한 커널에서는 Secrets 기능 자체가 안 먹혀서, 그 대안으로 값을 직접 박아 넣는 방식을 쓰고 있는 구조였습니다.
- 실제로 predict.py에도 1순위로 os.environ에서 값을 읽고(=주입된 값), 값이 없을 때만 2순위로 Kaggle Secrets(user_secrets.get_secret(...))를 시도하도록 되어 있어서, 제가 등록한 Secrets는 지금 구조에서는 거의 항상 안 쓰이고 있는 상태였습니다.
- 제가 Kaggle Secrets 등록 자체는 Kaggle 노트북 편집 화면의 Add-ons → Secrets 메뉴로 등록했고, 이름도 SUPABASE_URL / SUPABASE_KEY(및 SUPABASE_SERVICE_ROLE_KEY)로 코드와 동일하게 맞췄습니다.
제가 여쭤보고 싶은 건:
1. 혹시 제가 Secrets 등록 과정이나 코드 설정(.env, kernel-metadata.json 등)에서 뭔가 빠뜨리거나 잘못한 부분이 있어서 이런 현상이 생긴 걸까요? ㅠㅠ
2. 이게 강의에서 의도하신 정상적인 설계(=Kaggle Secrets는 폴백용이고, 실제로는 매번 키를 직접 주입하는 방식)가 맞는지
확인 부탁드립니다. 감사합니다.
참고 1 : 캐글 실행시 마다 재생성된 predict.ipynb 파일

참고 2 : 캐글 노트북

참고 3 : 캐글 시크릿키 등록

답변 2
1
안녕하세요, @yundyo님.
아주 정확하게 분석하셨습니다. 결론부터 말씀드리면 잘못하신 부분은 없고, 현재 코드가 의도한 동작이 맞습니다.
1. 설정을 빠뜨리신 게 아닙니다.
Kaggle Secrets(UserSecretsClient)는 Kaggle 웹 UI에서 "Save & Run All"로 실행한 버전에만 붙습니다. 우리 서버처럼 kaggle kernels push(API)로 새 버전을 올리면 그 버전에는 Secrets가 따라오지 않아서 get_secret()이 Connection error로 실패합니다. kernel-metadata.json에 Secrets를 지정하는 옵션도 없습니다. 이건 Kaggle 쪽 제한이고 아직 해결되지 않은 이슈입니다. 등록하신 Secrets 이름과 위치는 모두 정상입니다.
2. 네, 의도한 설계입니다.
그래서 서버(ml_trigger_service.push_kernel)가 push 직전에 .env의 SUPABASE_URL과 service_role 키를 노트북 첫 셀에 직접 넣어서 올립니다. predict.py는 환경변수를 먼저 읽기 때문에 자동 실행에서는 항상 이 주입값이 쓰이고, 등록하신 Secrets는 UI에서 수동 실행할 때와 Kaggle이 이 문제를 고쳤을 때를 위한 폴백입니다. Kaggle에서 소스를 열었을 때 첫 셀에 실제 값이 보이는 것이 정상입니다.
3. 대신 아래 세 가지는 꼭 지켜 주세요. 노트북에 들어가는 키는 RLS를 우회하는 service_role 키입니다.
노트북을 반드시 Private로 유지하고, Public 전환·링크 공유·협업자 추가를 하지 마세요. 버전 히스토리에도 키가 남습니다.
kaggle_notebook/predict.ipynb는
.gitignore에 있습니다. 예전에 clone하셔서 아직 git이 추적 중이면git rm --cached kaggle_notebook/predict.ipynb후 커밋해 주세요.git ls-files kaggle_notebook에 predict.ipynb가 안 나오면 정상입니다.혹시 노트북이 공개됐거나 ipynb를 어딘가 올리신 적이 있다면 Supabase Dashboard → Project Settings → API에서 service_role 키를 재발급하고
.env를 갱신하세요.
참고로 노트북 소스에 키를 남기고 싶지 않다면 Kaggle 공식 포럼 가이드처럼 비공개 Dataset에 키 파일을 올려 dataset_sources로 붙이는 방법도 있습니다. 다만 신뢰 경계는 본인 Kaggle 계정으로 동일하고 설정 단계만 늘어나서 강의에서는 주입 방식을 채택했습니다.
제가 최근에 급한 일 처리로 답변이 다소 늦어서 죄송합니다.
혹시 해결이 안되시거나 추가로 궁금한 부분이 있으시다면 언제든 편하게 질문 주세요~
좋은 질문 주셔서 감사합니다.
0
안녕하세요, 인프런 AI 인턴입니다.
yundyo님, 첨부해 주신 내용과 설명을 보면 Secrets 등록을 잘못해서 발생한 현상이라기보다, push_kernel() 과정에서 실제 키를 노트북 코드에 주입하도록 구현된 것이 원인으로 보입니다.
1. 현재 현상의 원인
predict.ipynb의 첫 번째 셀에 다음과 같이 실제 값이 들어간다면,
import os
os.environ["SUPABASE_URL"] = "https://실제-url"
os.environ["SUPABASE_KEY"] = "실제-key"
Kaggle Secrets가 자동으로 노출된 것이 아닙니다.
predict.py를 읽는 과정에서 .env의 값을 가져와 새로운 노트북 셀에 기록한 뒤, 그 결과물을 Kaggle에 업로드하고 있는 구조입니다.
따라서 다음 설정들은 이 문제를 해결하지 못합니다.
- Kaggle Secrets 이름을 정확하게 등록하는 것
kernel-metadata.json에 환경 변수를 추가하는 것
.env에 키를 저장하는 것
노트북 파일 자체에 키가 기록된 뒤 Kaggle에 업로드되기 때문입니다.
2. 이것이 정상적인 보안 설계인지
일반적으로는 정상적인 설계라고 보기 어렵습니다.
Kaggle API로 생성한 커널에서 UserSecretsClient가 동작하지 않는 문제가 실제로 있을 수는 있지만, 그 문제의 해결책으로 Supabase 키를 노트북 소스에 직접 삽입하면 다음과 같은 위험이 생깁니다.
- Kaggle 노트북 소스에 키가 저장됨
- 노트북 버전이나 실행 기록에 키가 남을 수 있음
- 공유 설정이나 권한 변경으로 키가 노출될 수 있음
- 로그, 출력 결과, 백업 파일 등에 키가 포함될 수 있음
- 특히
SUPABASE_SERVICE_ROLE_KEY가 노출되면 데이터베이스 권한까지 악용될 수 있음
따라서 현재 구조에서 Kaggle Secrets는 말씀하신 것처럼 사실상 폴백으로만 사용되고 있으며, 실제 키를 직접 주입하는 방식이 강의 코드에 포함된 우회 설계일 가능성이 높습니다.
다만 강의 제작자가 API 커널에서 Secrets 연결이 불안정한 문제를 피하기 위해 임시로 넣었을 수는 있어도, 보안 관점에서는 권장하기 어렵습니다.
3. 지금 즉시 해야 할 조치
첨부 이미지와 노트북에 키 일부가 노출된 상태라면, 이미 노출되었다고 가정하는 것이 안전합니다.
특히 다음 키는 즉시 폐기하고 새로 발급하는 것을 권장합니다.
SUPABASE_SERVICE_ROLE_KEY
SUPABASE_KEY
Supabase에서 기존 키를 교체한 뒤 다음 위치도 모두 확인해 주세요.
- Kaggle Secrets
- 로컬
.env
- Kaggle 노트북 코드
- Kaggle 노트북 버전 및 실행 기록
- Git 저장소와 커밋 기록
- 로그 및 생성된
predict.ipynb파일
키를 새로 발급한 뒤에는 생성되는 노트북에 실제 값이 들어가지 않는지도 확인해야 합니다.
4. 권장하는 코드 구조
가장 안전한 방법은 predict.ipynb에 실제 값을 기록하지 않고, 실행 시점에 Kaggle Secrets에서 읽도록 하는 것입니다.
import os
try:
from kaggle_secrets import UserSecretsClient
user_secrets = UserSecretsClient()
os.environ["SUPABASE_URL"] = user_secrets.get_secret("SUPABASE_URL")
os.environ["SUPABASE_KEY"] = user_secrets.get_secret("SUPABASE_KEY")
os.environ["SUPABASE_SERVICE_ROLE_KEY"] = (
user_secrets.get_secret("SUPABASE_SERVICE_ROLE_KEY")
)
except Exception as e:
raise RuntimeError(
"Kaggle Secrets를 읽지 못했습니다. "
"노트북의 소스 코드에 키를 직접 삽입하지 않고 실행을 중단합니다."
) from e
핵심은 .env 값을 노트북 셀 문자열로 변환하지 않는 것입니다.
즉, 다음과 같은 로직은 제거하거나 수정해야 합니다.
# 지양해야 하는 방식
secret_value = os.getenv("SUPABASE_KEY")
notebook_cell = f'os.environ["SUPABASE_KEY"] = "{secret_value}"'
대신 다음처럼 노트북에는 키 이름과 조회 코드만 포함해야 합니다.
# 권장 방식
user_secrets.get_secret("SUPABASE_KEY")
5. API로 푸시한 커널에서 Secrets가 정말 동작하지 않는지 확인하는 방법
먼저 실제 키를 출력하지 않고 다음 정도만 테스트해 보시는 것이 좋습니다.
from kaggle_secrets import UserSecretsClient
user_secrets = UserSecretsClient()
value = user_secrets.get_secret("SUPABASE_URL")
print("SUPABASE_URL 조회 성공 여부:", bool(value))
실제 URL이나 키 값은 출력하지 않아야 합니다.
- 조회에 성공하면 직접 주입 로직을 제거하면 됩니다.
- API로 푸시한 커널에서 계속
Connection error가 발생하면 Kaggle API 커널과 Secrets 연동 제약이 있는지 확인해야 합니다.
- 그 경우에도 키를 소스에 직접 넣기보다는, 해당 방식의 자동 배포를 중단하거나 별도의 안전한 실행 환경을 사용하는 편이 좋습니다.
결론
yundyo님께서 Secrets를 잘못 등록하신 문제라기보다는, push_kernel()이 .env의 값을 읽어 predict.ipynb에 직접 기록하는 구조가 원인으로 보입니다.
따라서 현재 구현은 다음과 같이 정리할 수 있습니다.
현재 구현:
.env → 실제 키를 노트북 코드에 기록 → Kaggle에 업로드
권장 구현:
Kaggle에 키 없는 노트북 업로드 → 실행 시 Kaggle Secrets에서 조회
강의의 자동화 흐름상 임시 우회로 구현된 것일 수는 있지만, 실제 서비스 키, 특히 SERVICE_ROLE_KEY를 노트북에 직접 삽입하는 방식은 보안상 피해야 합니다.
첨부해 주신 이미지에서 키가 일부라도 노출되었으므로, 기존 키는 먼저 폐기하고 새 키로 교체하시는 것을 가장 우선으로 권장드립니다.
검색 대상 종목 선정
1
56
2
llm_decision_logs 미적재 문의
1
42
2
연동 문제
1
50
2
5-21 질문이요!
1
67
3
매수 실행 시점 관련
1
41
1
Opus/Sonnet 버전 관련 문의
1
58
2
섹션2 질문이요
1
65
2
섹션1.9 질문입니다!
1
86
3
git bash .env
1
64
1
알파벤티지 sleep(5) 관련 문의
1
75
2
실전 계좌에서 운영하고 계신 분 계신가요?
1
72
2
클로드
1
66
2
pip install -r requirements.txt
0
68
2
명령 프롬프트
0
72
2
slack 알림 연동 강의 관련
1
82
2
supabase_key 관련
1
92
3
python run.py 실행시 에러 문제
1
103
2
커서창
1
73
2
cursor 환경
1
74
2
개발 환경 준비와 프로젝트 구조 강의 관련
1
65
2
저장 공간
1
73
2
colab 코드 실행시 error
1
65
2
llm_decision_logs 저장 실패(실적 컬럼 불일치)를 어떻게 해결할까요?
2
107
4
kaggle notebook에 service key 설정이 누락된 것 같습니다
1
84
2





