주요 콘텐츠로 건너뛰기

Okta API Bearer 인증

Okta에서 발급한 OAuth 2.0 Bearer 토큰을 사용하여 Halo API에 대한 프로그래밍 방식 액세스를 인증합니다.

개요

Halo는 API-Access 서비스를 통해 REST API를 제공합니다. 모든 API 요청에는 Authorization 헤더에 유효한 Bearer 토큰이 포함되어야 합니다. 토큰은 OAuth 2.0 Client Credentials 흐름(머신 투 머신)을 사용하여 Okta에서 획득합니다.

이 가이드에서는 Halo API-Access 서비스의 Identity Provider로 Okta를 구성한 다음, Bearer 토큰 인증으로 통합을 테스트하는 방법을 안내합니다.

필수 조건

  • API-Access 서비스가 구성된 실행 중인 Halo 배포
  • 관리자 액세스 권한이 있는 Okta 조직
  • Halo용으로 구성된 Okta authorization server(참조: Okta Authorization Server)
  • API 클라이언트에서 Okta와 Halo API endpoint 모두로의 네트워크 액세스

설정

Okta에서 API 클라이언트 등록

machine-to-machine 애플리케이션 생성

  1. Okta Admin Console에 로그인합니다.
  2. Applications -> Applications -> Create App Integration -> API Services로 이동합니다.

Screenshot: Create API Services application in Okta

  1. 적절한 App integration 이름을 입력합니다. 예: Glasswall Halo API

Screenshot: API service app name in Okta

DPoP (proof of possession) 비활성화

  1. 애플리케이션의 General 탭 -> General Settings 섹션으로 이동한 다음 Edit를 클릭합니다.
  2. Proof of possession 아래에서 Require Demonstrating Proof of Possession (DPoP) header in token requests의 선택을 해제합니다.
  3. 저장합니다.

참고: Okta는 API Services 애플리케이션에 대해 기본적으로 DPoP를 활성화합니다. DPoP는 토큰을 클라이언트의 암호화 키에 바인딩하여 토큰 재사용 공격을 방지합니다. 그러나 Halo API-Access service는 현재 DPoP 토큰 검증을 지원하지 않으므로, Bearer token 인증이 작동하려면 이를 비활성화해야 합니다.

Screenshot: Disable DPoP in Okta application settings

클라이언트 자격 증명 구성

  1. Client ID를 기록해 두고 Client Secret을 생성합니다.

    export CLIENT_ID="<your-client-id>"
    export CLIENT_SECRET="<your-client-secret>"

보안 참고: 클라이언트 시크릿은 secrets manager(예: Azure KeyVault)를 사용하여 안전하게 저장하십시오. 시크릿을 소스 제어에 절대 커밋하지 마십시오.

Screenshot: Client ID and secret from Okta application

역할 구성(선택 사항)

  1. API 클라이언트에 라이선스 관리 엔드포인트에 대한 쓰기 액세스가 필요한 경우, authorization server에서 role 클레임이 구성되어 있고 Admin 값이 해당 클라이언트에 매핑되어 있는지 확인하세요(API Roles 참조).

참고: role 클레임이 없으면 API는 기본적으로 User role을 사용합니다. 각 role이 액세스할 수 있는 항목에 대한 자세한 내용은 API Roles to Action Mapping을 참조하세요.

issuer URI 및 audience 기록

  1. 사전 요구 단계에서 구성한 authorization server에서 다음 값을 확인하세요:

    export OKTA_ISSUER_URI="https://<your-okta-domain>/oauth2/<authorization-server-id>"
    export VALID_AUDIENCE="api://halo"

API 클라이언트용 액세스 policy 추가

  1. authorization server의 Access Policies 탭으로 이동합니다(Security -> API -> authorization server 선택 -> Access Policies).
  2. Add a new access policy:
    • 이름: 예: API Client Access
    • 설명: 예: Access policy for Halo API clients
    • 할당 대상: 위에서 생성한 API Services 클라이언트(2단계에서 애플리케이션 이름 glasswall-halo-api으로 검색)
  3. Add a rule:
    • 이름: 예: Allow API Clients
    • Grant type: Client Credentials
    • 다른 설정은 기본값으로 두거나 필요에 따라 토큰 수명을 조정하세요.

참고: Client Credentials grant에 대한 액세스 policies는 어떤 클라이언트(client_id 기준)가 토큰을 요청할 수 있는지 제어합니다. 이 흐름에는 사용자 컨텍스트가 없으므로 그룹 멤버십은 적용되지 않습니다. secrets manager를 통해 누가 client_idclient_secret을 보유하는지 제한하여 API 액세스를 안전하게 보호하세요.

Screenshot: API access policy on authorization server

Okta용 API-Access 서비스 구성

cdrplatform-api-access Helm chart는 Okta authorization server에서 발급한 Bearer 토큰을 검증하도록 구성해야 합니다. 이 chart는 인증 설정을 configuration values 키 아래에 노출합니다.

구성을 배포합니다

Note: The Authority and ValidIssuer must both be set to the Okta issuer URI. The API-Access service uses Authority to discover the JWKS (JSON Web Key Set) for token signature validation, and ValidIssuer to verify the iss claim in the token.

export HALO_DOMAIN=<your-halo-domain>
helm upgrade --install cdrplatform-api-access cdrplatform-api-access --reuse-values \
--set configuration.AuthenticationScheme="Bearer" \
--set configuration.Authentication__Schemes__Bearer__Authority="${OKTA_ISSUER_URI:?}" \
--set configuration.Authentication__Schemes__Bearer__ValidIssuer="${OKTA_ISSUER_URI:?}" \
--set configuration.Authentication__Schemes__Bearer__ValidAudiences__0="${VALID_AUDIENCE:?}" \
--set strategy.type="Recreate" \
--set ingress.enabled=true \
--set ingress.tls.enabled=true \
--set ingress.tls.domain="${HALO_DOMAIN:?}" \
--atomic

여러 audience (선택 사항)

여러 API 클라이언트 또는 애플리케이션이 서로 다른 audience로 Halo API에 액세스해야 하는 경우, 추가 ValidAudiences 항목을 추가합니다:

  --set configuration.Authentication__Schemes__Bearer__ValidAudiences__0="api://halo-api" \
--set configuration.Authentication__Schemes__Bearer__ValidAudiences__1="<second-client-id>" \
--set configuration.Authentication__Schemes__Bearer__ValidAudiences__2="<third-client-id>"

Halo API 사용

Bearer 토큰 가져오기

Client Credentials 흐름 (machine-to-machine)

이 흐름은 사용자 상호작용이 필요 없는 자동화 시스템, CI/CD 파이프라인 및 서비스 간 통합에 사용합니다.

export TOKEN_ENDPOINT="${OKTA_ISSUER_URI}/v1/token"

토큰 요청:

curl -s -X POST "${TOKEN_ENDPOINT}" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=${CLIENT_ID}" \
-d "client_secret=${CLIENT_SECRET}" \
-d "scope=halo.api"

응답 예시:

{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6Ikp...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "halo.api"
}

토큰 추출:

export ACCESS_TOKEN=$(curl -s -X POST "${TOKEN_ENDPOINT}" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=${CLIENT_ID}" \
-d "client_secret=${CLIENT_SECRET}" \
-d "scope=halo.api" | jq -r '.access_token')

API 요청 인증

모든 API 요청의 Authorization 헤더에 Bearer 토큰을 포함합니다:

export HALO_API_URL="https://<your-halo-domain>"

인증 확인

보호된 엔드포인트로 테스트합니다. 토큰이 없는 요청은 401을 반환해야 하고, 유효한 토큰이 있는 요청은 200을 반환해야 합니다:

# Without token - expect 401
curl -s -o /dev/null -w "%{http_code}" \
"${HALO_API_URL}/api/v1/policies"

# With token - expect 200
curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
"${HALO_API_URL}/api/v1/policies"

예: 처리할 파일 제출

curl -s -X POST \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-F "file=@/path/to/document.pdf" \
"${HALO_API_URL}/api/v1/rebuild/file" \
--output rebuilt_document.pdf

문제 해결

증상원인해결 방법
401 Unauthorized토큰이 만료되었거나 유효하지 않음새 토큰을 요청합니다. CLIENT_IDCLIENT_SECRET가 올바른지 확인합니다.
유효한 토큰으로 401 Unauthorized 발생Audience 불일치API-Access의 ValidAudiences가 토큰의 aud 클레임과 일치하는지 확인하세요.
403 ForbiddenAdminRoleMissing토큰에 Admin 역할이 누락됨권한 부여 서버에서 role 클레임을 구성하세요(API Roles 참조). 라이선스 관리 쓰기 작업에 필요합니다.
토큰 요청 실패잘못된 토큰 엔드포인트 URL권한 부여 서버 ID와 Okta 도메인을 확인하세요. /.well-known/openid-configuration을 확인하세요.
invalid_scope 오류Client Credentials와 함께 OIDC scope 사용됨halo.api 범위를 openid, profile 또는 email 대신 사용하세요.
invalid_dpop_proof 오류DPoP가 비활성화되지 않음API Services 애플리케이션에서 DPoP를 비활성화하세요(Disable DPoP 참조).
네트워크 시간 초과방화벽 또는 프록시 차단API 클라이언트가 Okta 토큰 엔드포인트와 Halo API 엔드포인트 모두에 연결할 수 있는지 확인하세요.