저희 조직은 Jira, Confluence, Slack, GitHub, AWS, Datadog 등 50여 개의 SaaS를 사용하고 있습니다. 기존에는 각 서비스마다 개별적으로 계정을 생성하고 관리했기 때문에 신규 입사자가 오면 온보딩에만 3일이 소요되었고, 반대로 퇴사자가 발생했을 때 미처 회수하지 못한 '고스트 계정'이 보안 홀로 작용할 위험이 컸습니다. 또한 직원들은 수십 개의 비밀번호를 외우기 힘들어 단순한 패턴을 사용하거나 포스트잇에 적어두는 등 비밀번호 관리 위생(Hygiene)이 심각하게 저하된 상태였습니다. 이러한 문제를 근본적으로 해결하기 위해 글로벌 1위 IAM 솔루션인 Okta를 도입하여 통합 인증 체계를 구축했습니다.
기존에 사내에서 Active Directory(AD)를 사용하고 있었으나, 클라우드 네이티브 환경(SaaS)과의 연동성에서 한계를 느꼈습니다. Okta는 7,000개 이상의 사전 정의된 OIN(Okta Integration Network)을 제공하여 대부분의 SaaS를 클릭 몇 번으로 연동할 수 있다는 점이 가장 큰 매력이었습니다. 또한 99.99%의 가용성과 강력한 MFA 정책 기능을 제공하여 'Zero Trust' 보안 모델의 시작점으로 적합하다고 판단했습니다.
자체 개발한 내부 어드민(Admin) 서비스에 Okta 로그인을 붙이는 과정을 예시로 설명합니다.
Okta Admin 콘솔에서 Create App Integration > OIDC - OpenID Connect > Web Application을 선택합니다.
http://localhost:8080/login/oauth2/code/okta (Spring Security 기본 경로)
Spring Boot는 spring-boot-starter-oauth2-client 라이브러리를 통해 표준 OIDC 연동을 아주 쉽게 지원합니다.
application.yml에 발급받은 정보를 입력합니다.
spring:
security:
oauth2:
client:
registration:
okta:
client-id: ${OKTA_CLIENT_ID}
client-secret: ${OKTA_CLIENT_SECRET}
scope: openid, profile, email, offline_access
provider:
okta:
issuer-uri: https://dev-12345678.okta.com/oauth2/default
그리고 SecurityConfig에서 OAuth2 로그인을 활성화합니다.
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/", "/public/**").permitAll()
.anyRequest().authenticated()
)
.oauth2Login(oauth2 -> oauth2
.loginPage("/login") // 커스텀 로그인 페이지 (옵션)
.defaultSuccessUrl("/dashboard", true)
);
return http.build();
}
}
SPA(Single Page Application) 환경에서는 okta-react 라이브러리를 사용하여 인증 토큰을 관리합니다.
PKCE(Proof Key for Code Exchange) 방식을 사용하여 Client Secret 노출 없이 안전하게 인증할 수 있습니다.
import { Security, LoginCallback } from '@okta/okta-react';
import { OktaAuth } from '@okta/okta-auth-js';
const oktaAuth = new OktaAuth({
issuer: 'https://dev-12345678.okta.com/oauth2/default',
clientId: '0oabcd1234effg',
redirectUri: window.location.origin + '/login/callback'
});
function App() {
return (
<Security oktaAuth={oktaAuth}>
<Route path="/login/callback" component={LoginCallback} />
<SecureRoute path="/dashboard" component={Dashboard} />
</Security>
);
}
단순히 로그인만 통합하는 것이 아니라, 접근 통제 정책을 세분화하여 보안을 강화했습니다.
모든 사용자는 로그인 시 반드시 Okta Verify 앱을 통한 Push 알림 승인 또는 생체 인증을 거치도록 정책을 설정했습니다. 특히 관리자(Admin) 그룹은 사내 네트워크 IP 대역 외에서 접근 시 더욱 강력한 인증(YubiKey 등)을 요구하도록 조건부 접근(Conditional Access) 정책을 적용했습니다.
회사가 지급하고 관리하는(MDM에 등록된) 기기에서만 주요 데이터에 접근할 수 있도록 Device Trust 설정을 추가했습니다. 이를 통해 개인 PC나 PC방 등 보안이 보장되지 않은 환경에서의 접근을 원천 차단했습니다.
가장 큰 성과는 입/퇴사 프로세스의 자동화입니다. HR 시스템(Workday)과 Okta를 연동하여, HR에 신규 입사자가 등록되면 Okta가 자동으로 계정을 생성하고, 직무(Department)에 따라 필요한 SaaS(Slack 채널, GitHub Organization 등)에 자동으로 초대합니다. 반대로 퇴사 처리가 되면 즉시 Okta 계정이 비활성화되면서 연결된 모든 SaaS 세션이 만료됩니다. 이를 통해 SCIM(System for Cross-domain Identity Management) 프로토콜의 강력함을 체감할 수 있었습니다.
Okta 도입 후 비밀번호 초기화 요청 티켓이 월 100건에서 5건 미만으로 95% 감소했습니다. 사용자들은 하나의 계정으로 모든 업무 시스템에 물 흐르듯 접근할 수 있게 되어 만족도가 매우 높습니다. 무엇보다 보안 담당자로서, '누가, 언제, 어디서, 어떤 서비스에 접근했는지'를 중앙에서 투명하게 모니터링할 수 있는 가시성(Visibility)을 확보했다는 점이 가장 큰 수확입니다. 이제 Identity는 새로운 보안 경계(Identity is the new perimeter)입니다.