본문으로 바로가기 본문 바로가기
WIKI 기술 지식 베이스

OpenID Connect

원문 보기 위키 갱신

Fly Machines는 AWS, Azure, GCP 같은 서드파티 서비스나 클라우드 제공자에 접근해야 할 때가 있어요. 이 서드파티에 인증하려면 Machine이 클라우드 제공자에게 비밀번호나 토큰 같은 자격 증명을 제공해야 해요. 보통 이런 자격 증명은 fly secrets로 저장된 다음 Machine의 환경 변수로 전달돼요.

하지만 이 접근 방식은 서드파티 플랫폼에 하드코딩된 장수 자격 증명을 만드는 것이고, 많은 토큰을 관리하거나 여러 앱에 걸쳐 같은 토큰을 공유하는 것과 관련 있어요.

OpenID Connect (OIDC)를 사용하면 서드파티 플랫폼에서 직접 수명이 짧은 액세스 토큰을 사용하는 더 안전한 접근이 가능해요. 유일한 조건은 서드파티 플랫폼이 OIDC 토큰을 지원해야 하고, Fly.io와 서드파티 사이에 신뢰 관계를 구축해야 한다는 것이에요. 현재 OIDC를 지원하는 제공자에는 Amazon Web Services, Azure, Google Cloud Platform, HashiCorp Vault 등이 있어요.

출처: 문서

본문

OpenID Connect (OIDC)의 이점

OIDC를 채택해 서드파티 서비스에 대한 접근을 관리하면 앱이 다음과 같은 좋은 보안 관행을 쉽게 사용할 수 있어요:

  • 하드코딩된 자격 증명 없음 — 이것들은 종종 Machine과 앱에 걸쳐 공유돼요. OIDC는 모든 Machine이 자신만의 자격 증명을 가질 수 있게 해줘요.
  • 서드파티의 인증(authN) 및 권한 부여(authZ) 도구를 활용한 Machine의 서드파티 리소스 접근에 대한 세밀한 제어.
  • 자격 증명 회전: 서드파티가 발급한 자격 증명은 만료되기 전 15분 동안만 유효해요.

OpenID Connect 이해하기

토큰 엔드포인트에 대한 모든 요청은 고유한 Json Web Token (JWT)을 생성해요. 이 JWT를 서드파티에 주면, 발급자(iss) 클레임의 엔드포인트에 호스팅된 OIDC 구성에 대해 토큰을 검증해요. 아래는 발급된 OIDC 토큰의 예시예요. 여기서 유용한 기능은 주체(sub) 클레임이 Machine의 조직 이름, 앱 이름, Machine 이름을 참조한다는 것이에요. 이를 통해 클레임에 대해 정규식 검사를 만들어 허용된 토큰을 특정 앱이나 Machine으로 제한할 수 있어요.

{
    "app_id": "11111111",
    "app_name": "example-app",
    "aud": "https://fly.io/exmaple-org",
    "exp": 1712099653,
    "iat": 1712099053,
    "image": "docker-hub-mirror.fly.io/you/image:latest",
    "image_digest": "sha256:2c1cdaded1b3820020c9dc9fdd1d6e798d6f6ca36861bb6ae64019fad6be9ee3",
    "iss": "https://oidc.fly.io/exmaple-org",
    "jti": "93ca09e1-70e0-477b-a260-1d8fcd4ef4f4",
    "machine_id": "148e21ea7e46e8",
    "machine_name": "example-machine",
    "machine_version": "01HTGGC1TZ2JHK83J4AC0R3VET",
    "nbf": 1712099053,
    "org_id": "11111111",
    "org_name": "example-org",
    "region": "sea",
    "sub": "example-org:example-app:example-machine"
}

OIDC 토큰 클레임 사용자 지정하기

토큰을 사용자 지정하면 인증하는 플랫폼에서 강력한 권한 부여 절을 만들 수 있어요. 예를 들어 AWS에서 특정 aud와 sub 클레임과 일치하는 토큰만 역할을 가정(assume)할 수 있도록 요구할 수 있어요. 이를 통해 특정 Fly.io 앱이나 Machine에만 자격 증명을 잠그고 제공할 수 있어요.

POST 요청의 본문에 aud 값을 제공해 토큰의 청중(aud) 클레임을 사용자 지정할 수 있어요. 이를 통해 토큰의 수신자를 지정할 수 있어요. aud 클레임이 sts.amazonaws.com으로 설정된 curl 요청에서 이렇게 보여요.

curl --unix-socket /.fly/api -X POST "http://localhost/v1/tokens/oidc" --data '{"aud":"sts.amazonaws.com"}'

AWS의 OpenID Connect 신뢰 정책

IAM 역할의 신뢰 정책을 활용해 조직의 어떤 Machine이 AWS에서 역할을 가정할 수 있는지 제한할 수 있어요. 예를 들어 다음 정책은 조직 내 foo-bar 앱의 Machine만 그 역할(부착된 역할)을 가정할 수 있게 해줘요.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::123456123456:oidc-provider/oidc.fly.io/<org-name>"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
              "StringEquals": {
                "oidc.fly.io/<org-name>:aud": "sts.amazonaws.com",
              },
              "StringLike": {
                "oidc.fly.io/<org-name>:sub": "org-name:foo-bar:*"
              }
            }
        }
    ]
}

Fly Machine에서 S3 버킷 읽기

Fly Machine을 사용해 S3 버킷을 읽으려면 먼저 AWS에 OIDC 제공자를 만들어 AWS와 Fly.io 사이의 신뢰를 설정하고, Machine이 가정할 역할 정책에 신뢰 정책을 부착해야 해요. 앱을 이미 Dockerfile에 패키징했다면, 다음 단계로 S3 버킷을 읽을 수 있어요:

  1. Dockerfile이 있는 디렉터리에서 fly launch를 실행해 Fly.io 앱을 만들어요.

  2. 앱을 시작할 조직의 slug를 찾아요.

    fly orgs list
    
  3. AWS 계정에 조직 slug와 다음 설정으로 OpenID Connect Identity provider를 만들어요:

    Provider URL: https://oidc.fly.io/<org-slug>
    Audience: sts.amazonaws.com
    
  4. 다음 설정으로 IAM Role을 만들어요:

  • Trusted Identity: Web Identity -> Identity Provider -> oidc.fly.io
  • AmazonS3ReadOnlyAccess 정책 선택.
  1. fly.toml에 AWS_ROLE_ARN을 환경 변수로 설정해요.

    [env]
      AWS_ROLE_ARN = "arn:aws:iam::<ACCOUNT_ID>:role/<ROLE_NAME>"
    
  2. 앱을 배포하면 AWS SDK가 나머지를 처리해요.

    fly deploy
    

메모: 개인 조직(개인 org)으로 이걸 설정한다면 slug를 찾기가 조금 더 어려울 수 있는데, 대시보드에서 "Apps"를 클릭했을 때 URL에서 찾을 수 있어요.

더 알아보기 (Learn more)