티스토리 뷰

반응형

LangChain 백엔드 인증은 어떻게 붙일까? FastAPI JWT 로그인과 사내 도우미 권한 분리까지 실전 예제로 정리

LangChain + FastAPI 백엔드를 운영 환경에 올리면, 다음으로 바로 붙어야 하는 건 인증(Authentication)과 권한(Authorization) 입니다. FastAPI 공식 문서는 OAuth2 Password 흐름과 Bearer JWT 토큰 기반 인증 예제를 실제 애플리케이션에 사용할 수 있는 형태로 안내하고 있고, OAuth2 scopes를 이용해 권한 범위를 나누는 방식도 설명합니다. LangChain 쪽은 agent가 tool을 쓰는 구조라서, “누가 이 endpoint를 호출했는지”뿐 아니라 “어떤 사용자가 어떤 tool까지 쓸 수 있는지”를 같이 설계하는 게 중요합니다. 또한 guardrails와 human-in-the-loop는 민감한 tool 호출 앞에서 deterministic 제어를 넣는 방법으로 공식 문서에 정리돼 있습니다. 검색에 잘 걸리는 글은 질문형 제목, 첫 문단 정답 요약, 정의 문장, FAQ, 비교표, 출처, 실행 가능한 코드가 중요하다는 메모 방향도 이번 글 구성에 반영했습니다. (fastapi.tiangolo.com)

이쯤 되면 이런 문제가 바로 보입니다.

  • 아무나 /assistant/ask를 치면 안 되는데?
  • 사내 정책은 전 직원이 봐도 되지만, 요청 상태는 본인 것만 봐야 하지 않나?
  • 어떤 tool은 조회만 되고, 어떤 tool은 승인이나 관리자 권한이 있어야 하지 않나?
  • streaming endpoint도 똑같이 인증을 걸어야 하나?

이 글은 바로 그 지점을 정리합니다.


한 줄 요약

LangChain 백엔드 인증의 가장 현실적인 시작은 FastAPI의 OAuth2 Password + JWT Bearer 토큰으로 로그인/인증을 붙이고, endpoint 레벨에서 current_user를 주입한 뒤, LangChain agent와 tool 쪽에서는 사용자 권한과 허용된 tool 범위를 함께 넘겨주는 구조입니다. FastAPI는 OAuth2PasswordBearer와 JWT 예제를 공식적으로 제공하고, OAuth2 scopes로 권한 분리를 확장할 수 있다고 설명합니다. LangChain은 middleware와 guardrails, human-in-the-loop를 통해 민감한 tool 호출을 제어할 수 있다고 안내합니다. (fastapi.tiangolo.com)


이 글에서 다루는 내용

  • LangChain 백엔드에 왜 인증이 꼭 필요한가
  • FastAPI JWT 로그인 구조를 어떻게 붙일까
  • /assistant/ask endpoint에 로그인 보호를 거는 법
  • 사용자 정보와 권한을 agent/tool에 어떻게 전달할까
  • 조회성 tool과 민감한 tool은 어떻게 나눠야 할까
  • OAuth2 scopes와 LangChain guardrails/HITL은 어디서 쓰나
  • 실무에서 자주 하는 실수와 FAQ

LangChain 백엔드 인증이란 무엇인가?

LangChain 백엔드 인증은 누가 agent를 호출하는지 확인하고, 그 사용자에게 허용된 범위 안에서만 문서 검색·상태 조회·tool 실행이 일어나도록 제한하는 구조입니다. FastAPI 공식 문서는 인증(authentication)과 권한(authorization)을 위해 OAuth2와 Bearer token 흐름을 안내하고, scopes로 세밀한 권한을 나눌 수 있다고 설명합니다. LangChain은 agent loop 안에서 tool 사용이 일어나므로, tool 호출 전 deterministic 제어가 필요한 경우 middleware와 guardrails를 쓰는 흐름을 공식 문서에서 설명합니다. (fastapi.tiangolo.com)

쉽게 말하면:

  • 인증: 이 사람이 누구인가
  • 권한: 이 사람이 무엇을 할 수 있는가

LLM 백엔드에서 이 둘은 더 중요합니다.
왜냐면 agent는 그냥 답만 하는 게 아니라, 필요하면 tool을 호출해서 실제 시스템을 건드릴 수도 있기 때문입니다.


왜 배포 다음 글이 인증이어야 할까

업로드해주신 메모에서도 검색에 잘 걸리는 기술 글은 문제 상황 → 바로 답 → 구조 설명 → 코드 → FAQ 흐름이 중요하다고 정리돼 있었는데, 배포 다음 단계에서 가장 검색 의도가 분명한 질문 중 하나가 바로 “FastAPI JWT 인증”, “LangChain 백엔드 권한”, “사내 도우미 로그인” 같은 키워드입니다. 실제로도 운영에 올리면 이게 가장 먼저 막히는 부분이에요.

왜냐면 배포까지 끝나면 이제 진짜 서비스처럼 보여서요.

그 순간부터는 “잘 답하냐”보다
누가 이걸 쓸 수 있냐가 더 중요해집니다.

특히 사내 도우미라면:

  • 인사 정책: 직원이면 가능
  • 요청 상태: 본인 요청만 가능
  • 관리자 전용 조회: 특정 role만 가능
  • 변경성 action tool: 승인 필요

이런 구분이 필요합니다.


인증 구조를 가장 단순하게 보면

이번 글에서는 제일 현실적인 출발점으로 갑니다.

  1. 로그인 endpoint에서 JWT 발급
  2. 보호된 endpoint에서 Bearer 토큰 검증
  3. current_user를 FastAPI dependency로 주입
  4. LangChain agent 호출 시 사용자 정보를 함께 전달
  5. tool 내부에서 사용자 role / user_id 기준으로 제한

FastAPI 공식 문서는 OAuth2PasswordBearer를 dependency로 쓰고, JWT를 발급·검증하는 예제를 제공합니다. “실제로 애플리케이션에서 사용할 수 있다”고까지 설명하고 있어요. (fastapi.tiangolo.com)


프로젝트 구조

이전 글 구조를 그대로 이어갑니다.

app/
├── main.py
├── core/
│   ├── config.py
│   ├── logging.py
│   └── security.py
├── schemas/
│   ├── assistant.py
│   └── auth.py
├── tools/
│   ├── policy.py
│   ├── request_status.py
│   └── summary.py
├── prompts/
│   └── assistant.py
├── agents/
│   └── internal_assistant.py
├── services/
│   └── assistant_service.py
├── routers/
│   ├── assistant.py
│   └── auth.py
└── infra/
    ├── memory.py
    └── tracing.py

이번 글에서 핵심으로 추가되는 파일은 두 개입니다.

  • core/security.py
  • routers/auth.py

requirements.txt

FastAPI JWT 예제는 pwdlib와 PyJWT를 사용합니다. FastAPI 공식 문서 예시도 이 흐름을 기준으로 되어 있습니다. (fastapi.tiangolo.com)

fastapi==0.112.0
uvicorn[standard]==0.30.6
langchain==1.0.3
langchain-openai==1.0.1
langgraph==1.0.2
pydantic==2.11.7
pydantic-settings==2.3.4
python-dotenv==1.0.1
pwdlib==0.2.0
PyJWT==2.9.0
python-multipart==0.0.9

python-multipart는 OAuth2PasswordRequestForm을 받을 때 필요합니다. FastAPI security 튜토리얼은 form 기반 로그인 흐름을 사용합니다. (fastapi.tiangolo.com)


1. 인증/권한용 스키마 만들기

반응형

app/schemas/auth.py

from typing import Literal
from pydantic import BaseModel, Field


class Token(BaseModel):
    access_token: str
    token_type: str = "bearer"


class TokenData(BaseModel):
    username: str
    scopes: list[str] = Field(default_factory=list)


class User(BaseModel):
    username: str
    full_name: str
    disabled: bool = False
    role: Literal["employee", "manager", "admin"] = "employee"
    scopes: list[str] = Field(default_factory=list)

FastAPI는 request/response body를 Pydantic 모델로 다루는 방식을 기본으로 안내하고, security 쪽도 결국 dependency + typed model 조합으로 가는 흐름입니다. (fastapi.tiangolo.com)


2. 핵심: JWT 발급과 검증 로직 만들기

app/core/security.py

from datetime import datetime, timedelta, timezone
from typing import Annotated

import jwt
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, SecurityScopes
from jwt.exceptions import InvalidTokenError
from pwdlib import PasswordHash

from app.schemas.auth import TokenData, User

# 실제 서비스에선 DB 조회로 교체
fake_users_db = {
    "alice": {
        "username": "alice",
        "full_name": "Alice Kim",
        "hashed_password": PasswordHash.recommended().hash("secret123"),
        "disabled": False,
        "role": "employee",
        "scopes": ["assistant:ask"],
    },
    "manager1": {
        "username": "manager1",
        "full_name": "Manager Lee",
        "hashed_password": PasswordHash.recommended().hash("secret123"),
        "disabled": False,
        "role": "manager",
        "scopes": ["assistant:ask", "request:read_all"],
    },
    "admin1": {
        "username": "admin1",
        "full_name": "Admin Park",
        "hashed_password": PasswordHash.recommended().hash("secret123"),
        "disabled": False,
        "role": "admin",
        "scopes": ["assistant:ask", "request:read_all", "assistant:admin"],
    },
}

SECRET_KEY = "CHANGE_THIS_IN_PRODUCTION"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 60

password_hash = PasswordHash.recommended()
oauth2_scheme = OAuth2PasswordBearer(
    tokenUrl="/auth/token",
    scopes={
        "assistant:ask": "Call the assistant endpoints",
        "request:read_all": "Read all request statuses",
        "assistant:admin": "Admin level assistant operations",
    },
)


def verify_password(plain_password: str, hashed_password: str) -> bool:
    return password_hash.verify(plain_password, hashed_password)


def authenticate_user(username: str, password: str) -> User | None:
    raw_user = fake_users_db.get(username)
    if not raw_user:
        return None
    if not verify_password(password, raw_user["hashed_password"]):
        return None
    return User(
        username=raw_user["username"],
        full_name=raw_user["full_name"],
        disabled=raw_user["disabled"],
        role=raw_user["role"],
        scopes=raw_user["scopes"],
    )


def create_access_token(data: dict, expires_delta: timedelta | None = None) -> str:
    to_encode = data.copy()
    expire = datetime.now(timezone.utc) + (expires_delta or timedelta(minutes=15))
    to_encode.update({"exp": expire})
    return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)


async def get_current_user(
    security_scopes: SecurityScopes,
    token: Annotated[str, Depends(oauth2_scheme)],
) -> User:
    authenticate_value = f'Bearer scope="{security_scopes.scope_str}"' if security_scopes.scopes else "Bearer"

    credentials_exception = HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="Could not validate credentials",
        headers={"WWW-Authenticate": authenticate_value},
    )

    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        username = payload.get("sub")
        token_scopes = payload.get("scopes", [])
        if username is None:
            raise credentials_exception
        token_data = TokenData(username=username, scopes=token_scopes)
    except InvalidTokenError:
        raise credentials_exception

    raw_user = fake_users_db.get(token_data.username)
    if raw_user is None:
        raise credentials_exception

    user = User(
        username=raw_user["username"],
        full_name=raw_user["full_name"],
        disabled=raw_user["disabled"],
        role=raw_user["role"],
        scopes=raw_user["scopes"],
    )

    for scope in security_scopes.scopes:
        if scope not in token_data.scopes:
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail="Not enough permissions",
                headers={"WWW-Authenticate": authenticate_value},
            )

    return user

이 코드는 FastAPI 공식 OAuth2 + JWT 예제를 바탕으로, scope 개념만 조금 확장한 형태입니다. FastAPI는 secure password hashing과 Bearer JWT 흐름, OAuth2 scopes까지 공식 문서로 제공합니다. (fastapi.tiangolo.com)

여기서 중요한 포인트

  • OAuth2PasswordBearer로 토큰 dependency 정의
  • JWT의 sub에 username 저장
  • JWT의 scopes에 권한 범위 저장
  • endpoint에서 필요한 scope를 요구 가능

즉 이 단계부터는
“로그인했는가”뿐 아니라
**“무슨 범위를 가진 로그인인가”**까지 다룰 수 있습니다.


3. 로그인 endpoint 만들기

app/routers/auth.py

from datetime import timedelta
from typing import Annotated

from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordRequestForm

from app.core.security import (
    ACCESS_TOKEN_EXPIRE_MINUTES,
    authenticate_user,
    create_access_token,
)
from app.schemas.auth import Token

router = APIRouter(prefix="/auth", tags=["auth"])


@router.post("/token", response_model=Token)
async def login_for_access_token(
    form_data: Annotated[OAuth2PasswordRequestForm, Depends()],
) -> Token:
    user = authenticate_user(form_data.username, form_data.password)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Incorrect username or password",
            headers={"WWW-Authenticate": "Bearer"},
        )

    access_token = create_access_token(
        data={
            "sub": user.username,
            "scopes": user.scopes,
        },
        expires_delta=timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES),
    )
    return Token(access_token=access_token)

FastAPI 공식 문서는 OAuth2PasswordRequestForm으로 로그인 폼을 받고, JWT access token을 발급하는 전체 예제를 제공합니다. (fastapi.tiangolo.com)


4. /assistant/ask endpoint를 보호하기

이제 사내 도우미 endpoint에 인증을 붙입니다.

app/routers/assistant.py

from typing import Annotated

from fastapi import APIRouter, Depends, HTTPException, Security

from app.core.security import get_current_user
from app.schemas.assistant import AskRequest, AskResponse
from app.schemas.auth import User
from app.services.assistant_service import ask_assistant

router = APIRouter(prefix="/assistant", tags=["assistant"])


@router.post("/ask", response_model=AskResponse)
async def ask(
    request: AskRequest,
    current_user: Annotated[User, Security(get_current_user, scopes=["assistant:ask"])],
) -> AskResponse:
    try:
        return ask_assistant(
            session_id=request.session_id,
            question=request.question,
            current_user=current_user,
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

FastAPI는 security dependency와 OAuth2 scopes를 결합하는 패턴을 공식적으로 설명합니다. 즉 이 endpoint는 이제 로그인된 사용자 중에서도 assistant:ask scope가 있는 사람만 접근 가능합니다. (fastapi.tiangolo.com)


5. 사용자 정보를 LangChain agent/service로 넘기기

이 부분이 진짜 중요합니다.

인증은 FastAPI에서 끝나지 않습니다.
LangChain agent와 tool도 누가 요청했는지 알아야 해요.

app/services/assistant_service.py

from app.agents.internal_assistant import get_agent
from app.schemas.assistant import AskResponse
from app.schemas.auth import User


def ask_assistant(session_id: str, question: str, current_user: User) -> AskResponse:
    agent = get_agent()

    result = agent.invoke(
        {
            "messages": [
                {
                    "role": "user",
                    "content": question,
                }
            ],
            "user_context": {
                "username": current_user.username,
                "role": current_user.role,
                "scopes": current_user.scopes,
            },
        },
        {
            "configurable": {
                "thread_id": session_id,
            }
        },
    )

    structured = result["structured_response"]

    return AskResponse(
        answer=structured.answer,
        response_type=structured.response_type,
        used_tools=structured.used_tools,
        sources=structured.sources,
    )

여기서 핵심은 이겁니다.

인증된 사용자 정보는 FastAPI dependency에서 끝나지 말고, agent 쪽에도 같이 전달돼야 한다.

그래야 나중에 이런 게 가능해집니다.

  • 본인 요청만 조회
  • 관리자만 전체 요청 조회
  • 특정 role만 특정 tool 사용

LangChain context engineering 문서는 agent가 model call과 tool execution 사이에서 state/context를 참고하며 행동을 결정한다고 설명합니다. یعنی user context도 결국 중요한 agent context가 될 수 있어요. (docs.langchain.com)


6. Tool 레벨 권한 분리 예제

이제 정말 실무적인 부분입니다.

예를 들어 get_request_status는
일반 직원은 본인 요청만 볼 수 있고,
manager는 팀 요청,
admin은 전체 요청을 볼 수 있게 할 수 있습니다.

import json
from langchain.tools import tool


@tool
def get_request_status(request_id: str, requester_username: str, requester_role: str) -> str:
    """Get the status of an internal request or ticket by request ID.

    Use this tool when the user asks for the latest state of a request,
    ticket, approval, or internal work item.
    """
    mock_requests = {
        "1024": {
            "request_id": "1024",
            "status": "승인 대기",
            "owner": "총무팀",
            "summary": "노트북 교체 요청",
            "requested_by": "alice",
        },
        "2048": {
            "request_id": "2048",
            "status": "처리 완료",
            "owner": "IT 지원팀",
            "summary": "사내 VPN 권한 부여",
            "requested_by": "bob",
        },
    }

    data = mock_requests.get(request_id)
    if not data:
        return json.dumps(
            {
                "found": False,
                "request_id": request_id,
                "message": "해당 요청 ID를 찾지 못했습니다.",
            },
            ensure_ascii=False,
        )

    if requester_role not in {"manager", "admin"} and data["requested_by"] != requester_username:
        return json.dumps(
            {
                "found": False,
                "request_id": request_id,
                "message": "이 요청을 조회할 권한이 없습니다.",
            },
            ensure_ascii=False,
        )

    return json.dumps(
        {
            "found": True,
            "request": data,
        },
        ensure_ascii=False,
    )

이 구조가 좋은 이유는 단순합니다.

  • endpoint 권한
  • tool 권한

이중으로 막을 수 있기 때문입니다.

FastAPI scopes는 endpoint 접근 권한을 다루고, tool 내부 권한은 실제 데이터 접근 범위를 다룹니다. 이 둘은 역할이 다릅니다.


7. 민감한 tool은 FastAPI 인증만으로 부족한 경우가 있다

여기서 LangChain guardrails와 HITL이 왜 나오는지 감이 옵니다.

예를 들어 이런 tool이 있다고 해봅시다.

  • 이메일 발송
  • 요청 승인
  • 사용자 삭제
  • 금액 수정

이런 건 “로그인했고 admin이니까 바로 실행”만으로 끝내기 위험할 수 있어요.

LangChain 공식 문서는 guardrails를 deterministic enforcement 용도로 설명하고, Human-in-the-Loop middleware는 민감한 tool call 앞에서 execution을 멈추고 사람 승인을 기다리게 할 수 있다고 안내합니다. 특히 파일 쓰기, SQL 실행, 고위험 operation에 유용하다고 되어 있습니다. (docs.langchain.com)

즉 실무에서는 보통 이렇게 갑니다.

조회성 tool

  • FastAPI 인증 + role 기반 제한

변경성 / 파괴성 tool

  • FastAPI 인증 + role 기반 제한 + HITL 승인

이 구분이 꽤 중요합니다.


8. OAuth2 scopes는 언제 써야 할까

FastAPI 공식 문서는 OAuth2 scopes를 “고급 주제”로 소개하지만, 권한을 API 단위로 나누고 싶을 때 꽤 유용하다고 설명합니다. (fastapi.tiangolo.com)

예를 들어 이런 식으로 생각할 수 있습니다.

  • assistant:ask
  • request:read_all
  • assistant:admin

그럼 endpoint는 이렇게 분리됩니다.

  • 일반 사내 도우미 질문: assistant:ask
  • 전체 요청 상태 조회: request:read_all
  • 관리자 기능: assistant:admin

즉 scope는
HTTP/API 레벨의 권한 스위치라고 보면 편합니다.


9. 검색에 잘 걸리게 쓰려면 꼭 넣어야 하는 비교 포인트

업로드해주신 메모에서 A와 B의 차이, 비교표, FAQ가 AI 검색과 답변 인용에 잘 맞는다고 정리돼 있었는데, 인증 글에서도 이게 잘 먹힙니다. 그래서 이 비교는 꼭 넣는 게 좋습니다.

JWT 인증 vs 세션 인증 차이

구분JWT 인증세션 인증

상태 저장 보통 stateless 서버 세션 저장 필요
API 친화성 높음 전통 웹에 친화적
FastAPI 예제 공식 문서 제공 직접 구현 시 고려사항 많음
사내 API/앱 연동 유리 상대적으로 덜 유리

FastAPI 공식 문서는 OAuth2 + Bearer JWT 흐름을 실제 API 애플리케이션에 사용할 수 있는 형태로 보여줍니다. (fastapi.tiangolo.com)

endpoint 권한 vs tool 권한 차이

구분endpoint 권한tool 권한

적용 위치 FastAPI dependency LangChain tool 내부
목적 누가 API를 호출할 수 있나 호출 후 무엇까지 볼/할 수 있나
예시 assistant:ask scope 필요 본인 요청만 조회 가능

이 비교가 되게 중요합니다.
많은 분이 endpoint만 막으면 끝이라고 생각하는데, 실제론 tool 내부 데이터 접근 범위도 별도로 보는 게 맞습니다.


10. 실행 방법

1) 로그인해서 토큰 받기

curl -X POST "http://127.0.0.1:8000/auth/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username=alice&password=secret123"

예상 응답:

{
  "access_token": "eyJhbGciOi...",
  "token_type": "bearer"
}

2) 토큰으로 assistant 호출하기

curl -X POST "http://127.0.0.1:8000/assistant/ask" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -d '{
    "session_id": "alice-session-1",
    "question": "재택근무 정책 알려줘."
  }'

이 흐름은 FastAPI 공식 JWT 튜토리얼의 기본 패턴과 같습니다. (fastapi.tiangolo.com)


자주 하는 실수

실수 1. 인증만 붙이고 권한을 안 나눈다

로그인했다고 모든 요청을 다 볼 수 있으면 안 됩니다.

실수 2. endpoint 권한만 보고 tool 내부 제한을 안 둔다

특히 요청 상태나 민감 데이터는 tool 안에서도 한 번 더 체크하는 게 좋습니다.

실수 3. JWT secret을 코드에 하드코딩한 채 운영 간다

이건 반드시 환경변수나 시크릿 관리로 빼야 합니다.

실수 4. 변경성 tool에 사람 승인 없이 바로 연결한다

LangChain HITL은 바로 이런 상황을 위해 존재합니다. (docs.langchain.com)

실수 5. streaming endpoint에는 인증을 빼먹는다

스트리밍도 결국 같은 보호 대상입니다. 동일한 인증/권한 로직을 적용하는 게 맞습니다.


FAQ

Q. LangChain 백엔드는 꼭 JWT를 써야 하나요?

꼭 그렇지는 않습니다. 하지만 FastAPI 공식 문서는 OAuth2 Password + Bearer JWT 흐름을 실제 API에 쓸 수 있는 보안 예제로 제공하고 있어서, 사내 도우미나 앱/웹 API에 가장 현실적인 출발점 중 하나입니다. (fastapi.tiangolo.com)

Q. FastAPI OAuth2와 LangChain tool 권한은 둘 다 필요한가요?

네, 역할이 다릅니다. FastAPI OAuth2/scopes는 API 접근 권한을 다루고, LangChain tool 권한은 실제 데이터/행동 범위를 다룹니다. 둘 다 있는 편이 안전합니다.

Q. 관리자 기능은 endpoint를 따로 나누는 게 좋나요?

대체로 그렇습니다. assistant:admin 같은 scope를 따로 두고 admin endpoint 또는 admin-only tool 경로를 분리하는 편이 더 명확합니다.

Q. 변경성 tool은 어떻게 보호해야 하나요?

로그인 + role 기반 제한만으로 끝내지 말고, 가능하면 human-in-the-loop 승인 지점을 넣는 편이 좋습니다. LangChain HITL middleware는 tool call 전 실행을 멈추고 승인/수정/거절을 받을 수 있게 해줍니다. (docs.langchain.com)

Q. OAuth2 scopes는 초보자에게 과한가요?

작은 앱에서는 role만으로도 충분할 수 있습니다. 하지만 사내 도우미처럼 endpoint가 늘어나고 권한이 다양해지면 scope 구조가 꽤 유용해집니다. FastAPI도 scopes를 고급 주제로 설명하지만, API 권한 분리에 잘 맞는다고 안내합니다. (fastapi.tiangolo.com)


핵심 요약

  • LangChain 백엔드 인증의 가장 현실적인 시작은 FastAPI OAuth2 Password + JWT Bearer 입니다. (fastapi.tiangolo.com)
  • endpoint 보호는 FastAPI dependency/scopes로, 실제 데이터 접근 범위는 LangChain tool 내부 권한 체크로 나누는 게 좋습니다.
  • 사용자 정보는 FastAPI에서만 쓰지 말고, agent/service/tool에도 함께 전달해야 합니다.
  • 변경성 tool은 guardrails와 human-in-the-loop까지 고려하는 편이 안전합니다. (docs.langchain.com)
  • 검색에 잘 걸리는 기술 글처럼, 인증 글도 질문형 제목 + 첫 문단 정답 요약 + 비교표 + FAQ + 실행 코드 구조가 이해와 검색에 모두 유리합니다.

출처

  • FastAPI Security 튜토리얼: OAuth2 개념 및 OAuth2PasswordBearer 소개. (fastapi.tiangolo.com)
  • FastAPI OAuth2 + JWT 튜토리얼: password hashing, Bearer JWT 토큰 예제. (fastapi.tiangolo.com)
  • FastAPI OAuth2 scopes: 인증과 권한을 같은 OAuth2 흐름에서 나누는 방법. (fastapi.tiangolo.com)
  • LangChain Guardrails: deterministic enforcement, HITL 연결 문서. (docs.langchain.com)
  • LangChain Human-in-the-Loop: 민감한 tool call 앞에서 승인/수정/거절 가능한 middleware. (docs.langchain.com)
  • LangChain Context Engineering: agent loop와 context/state 개념. (docs.langchain.com)
  • 업로드해주신 “AI 검색에 잘 걸리는 글” 메모: 질문형 제목, 첫 문단 정답 요약, 비교표, FAQ, 구조화된 검색형 글쓰기 전략 반영.

LangChain, FastAPI, JWT, OAuth2, Bearer Token, AI Agent, 백엔드보안, 권한관리, 사내도우미, 주니어개발자

※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/06   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함
반응형