조직 관리
조직 관리 (API로)
org-level 관리 작업을 위한 몇 가지 핵심 LangSmith REST API 엔드포인트를 알려드릴게요.
출처: 문서
본문
이 페이지는 조직 관리 작업의 일부에 대한 참조입니다. 관련 배경 자료:
참고: 곧 해결될 몇 가지 제한사항이 있습니다:
- LangSmith SDK는 아직 이러한 조직 관리 작업을 지원하지 않습니다.
- Organization Admin 권한이 있는 조직 범위 서비스 키를 이러한 작업에 사용할 수 있습니다.
경고: 대상 워크스페이스를 지정하려면
X-Tenant-Id헤더를 사용하세요. 헤더가 없으면 작업은 키가 직접 생성된 워크스페이스(조직 범위가 아닌 경우)를 기본값으로 사용합니다.조직 범위 서비스 키로 워크스페이스 범위 리소스에 접근할 때
X-Tenant-Id를 지정하지 않으면 요청이403 Forbidden으로 실패합니다.
일반적으로 사용되는 엔드포인트와 사용 사례는 아래에 나열되어 있습니다. 사용 가능한 전체 엔드포인트 목록은 API 문서를 참고하세요. 모든 요청에 X-Organization-Id 헤더가 있어야 하고, 특정 워크스페이스에 범위가 지정된 요청에는 X-Tenant-Id 헤더가 있어야 합니다.
워크스페이스
사용자 관리
RBAC
구성원 관리
이 작업의 역할 ID 조회에는 RBAC 아래의 List roles를 사용해야 합니다. [조직|워크스페이스] 구성원 나열 엔드포인트(아래)가 응답하는 "id"는 이 작업에서 identity_id로 사용해야 합니다.
조직 수준:
- 활성 조직 구성원 나열
- 대기 중인 조직 구성원 나열
- 조직과 하나 이상의 워크스페이스에 사용자 초대. 사용자가 이미 조직 구성원이 아닐 때 사용합니다.
- 사용자의 조직 역할 업데이트
- 조직에서 구성원 제거
워크스페이스 수준:
참고: 이 파라미터들은 생략해야 합니다:
read_only(더 이상 사용하지 않음),password와full_name(기본 인증 전용)
API 키
보안 설정
참고: 이러한 변경에는 Organization Admin 권한이 필요합니다.
참고: 여기서 "공유 리소스(Shared resources)"는 공개 프롬프트, 공유 실행, 공유 데이터셋을 의미합니다.
경고: 이 설정을 업데이트하면 조직의 모든 리소스에 영향을 줍니다.
워크스페이스의 Settings > Shared 탭 또는 API로 이 설정을 업데이트할 수 있습니다:
- 조직 공유 설정 업데이트
unshare_all을 사용해 선택한 워크스페이스의 모든 공유 리소스를 공유 해제 -disable_public_sharing을 사용해 향후 리소스 공유 방지
이 설정들은 API로만 편집할 수 있습니다:
- PAT 생성 비활성화/활성화 (셀프 호스팅, Helm 차트 버전 0.11.25+에서 사용 가능)
pat_creation_disabled를 사용해 전체 조직에서 PAT 생성을 비활성화합니다.- PAT를 만들 수 없는 Organization Viewer 역할에 대한 정보는 관리자 가이드를 참고하세요.
- 셀프 호스팅 배포는 환경 변수로 모든 조직에서 PAT 생성을 전역적으로 비활성화할 수도 있습니다.
사용자 전용 엔드포인트
이 엔드포인트들은 사용자 범위이며 로그인한 사용자의 JWT가 필요하므로 UI를 통해서만 실행해야 합니다.
/api-key/current엔드포인트: 사용자의 PAT와 관련/sso/email-verification/send(Cloud 전용): SAML SSO와 관련
예제 코드
아래 예제 코드는 조직 관리와 관련된 몇 가지 일반적인 워크플로를 다룹니다. 코드에서 <replace_me>가 있는 곳마다 필요한 대체를 수행하세요.
import os
import requests
def main():
api_key = os.environ["LANGSMITH_API_KEY"]
# LANGSMITH_ORGANIZATION_ID is not a standard environment variable in the SDK, just used for this example
organization_id = os.environ["LANGSMITH_ORGANIZATION_ID"]
base_url = os.environ.get("LANGSMITH_ENDPOINT") # or "https://api.smith.langchain.com". Update appropriately for self-hosted installations or regional SaaS
headers = {
"Content-Type": "application/json",
"X-API-Key": api_key,
"X-Organization-Id": organization_id,
}
session = requests.Session()
session.headers.update(headers)
workspaces_path = f"{base_url}/api/v1/workspaces"
orgs_path = f"{base_url}/api/v1/orgs/current"
api_keys_path = f"{base_url}/api/v1/api-key"
# Create a workspace
workspace_res = session.post(workspaces_path, json={"display_name": "My Workspace"})
workspace_res.raise_for_status()
workspace = workspace_res.json()
workspace_id = workspace["id"]
new_workspace_headers = {
"X-Tenant-Id": workspace_id,
}
# Grab roles - this includes both organization and workspace roles
roles_res = session.get(f"{orgs_path}/roles")
roles_res.raise_for_status()
roles = roles_res.json()
# system org roles are 'Organization Admin', 'Organization User'
# system workspace roles are 'Admin', 'Editor', 'Viewer'
org_roles_by_name = {role["display_name"]: role for role in roles if role["access_scope"] == "organization"}
ws_roles_by_name = {role["display_name"]: role for role in roles if role["access_scope"] == "workspace"}
# Invite a user to the org and the new workspace, as an Editor.
# workspace_role_id is only allowed if RBAC is enabled (an enterprise feature).
new_user_email = "<replace_me>"
new_user_res = session.post(
f"{orgs_path}/members",
json={
"email": new_user_email,
"role_id": org_roles_by_name["Organization User"]["id"],
"workspace_ids": [workspace_id],
"workspace_role_id": ws_roles_by_name["Editor"]["id"],
},
)
new_user_res.raise_for_status()
# Add a user that already exists in the org to the new workspace, as a Viewer.
# workspace_role_id is only allowed if RBAC is enabled (an enterprise feature).
existing_user_email = "<replace_me>"
org_members_res = session.get(f"{orgs_path}/members")
org_members_res.raise_for_status()
org_members = org_members_res.json()
existing_org_member = next(
(member for member in org_members["members"] if member["email"] == existing_user_email), None
)
existing_user_res = session.post(
f"{workspaces_path}/current/members",
json={
"user_id": existing_org_member["user_id"],
"workspace_ids": [workspace_id],
"workspace_role_id": ws_roles_by_name["Viewer"]["id"],
},
headers=new_workspace_headers,
)
existing_user_res.raise_for_status()
# List all members of the workspace
members_res = session.get(f"{workspaces_path}/current/members", headers=new_workspace_headers)
members_res.raise_for_status()
members = members_res.json()
workspace_member = next(
(member for member in members["members"] if member["email"] == existing_user_email), None
)
# Update the user's workspace role to Admin (enterprise-only)
existing_user_id = workspace_member["id"]
update_res = session.patch(
f"{workspaces_path}/current/members/{existing_user_id}",
json={"role_id": ws_roles_by_name["Admin"]["id"]},
headers=new_workspace_headers,
)
update_res.raise_for_status()
# Update the user's organization role to Organization Admin
update_res = session.patch(
f"{orgs_path}/members/{existing_org_member['id']}",
json={"role_id": org_roles_by_name["Organization Admin"]["id"]},
)
update_res.raise_for_status()
# Create a new Service key
api_key_res = session.post(
api_keys_path,
json={"description": "my key"},
headers=new_workspace_headers,
)
api_key_res.raise_for_status()
api_key_json = api_key_res.json()
api_key = api_key_json["key"]
if __name__ == "__main__":
main()
더 알아보기
- API 문서 — 사용 가능한 전체 엔드포인트 목록.
- 조직·워크스페이스 개요 — 역할과 구조.