연결 소비
백엔드 플러그인이나 모듈은 연결 선언을 추가하고, 플러그인 범위의 연결 서비스를 요청하고, 조회 쿼리와 이해하는 인증 메서드로 ConnectionsService.find를 호출하여 연결을 소비해요.
출처: 문서
본문
백엔드 플러그인이나 모듈은 연결 선언을 추가하고, 플러그인 범위의 연결 서비스를 요청하고, 조회 쿼리와 이해하는 인증 메서드로 ConnectionsService.find를 호출하여 연결을 소비해요.
런타임 API 경계
공용 @backstage/connections 패키지에는 공유 서비스 계약, 연결 타입, 타입 헬퍼가 포함돼요. 서비스 참조와 선언 헬퍼는 비공개, 인라인된 @backstage/connections-node 패키지에 남아 있어요. 이 페이지의 전체 배선 예시는 이 실험적 경계가 완성되는 동안 Backstage 저장소의 프레임워크 코드에 적용돼요. 외부 플러그인 패키지는 @backstage/connections-node에 의존하면 안 돼요.
연결 의존성 선언
프레임워크 플러그인과 모듈은 registerInit를 호출하기 전에 register 동안 각 타입을 선언해요. 선언이 조회와 분리된 이유는 연결 선언 개념 을 참고하세요:
import { createBackendPlugin } from '@backstage/backend-plugin-api';import { connectionsServiceRef, declareConnection,} from '@backstage/connections-node';export const examplePlugin = createBackendPlugin({ pluginId: 'example', register(reg) { declareConnection(reg, { type: 'github', description: 'Reads repository metadata from GitHub', }); reg.registerInit({ deps: { connections: connectionsServiceRef, }, async init({ connections }) { // Use connections here. }, }); },});
선언은 하나의 플러그인 또는 모듈 등록에 적용돼요. 모듈이 GitHub를 사용하고 부모 플러그인도 GitHub를 사용하면 두 등록 모두 github 타입을 선언해요.
런타임은 선언되지 않은 조회를 거부해요. 이렇게 하면 연결 사용이 플러그인 메타데이터에 표시되고, 플러그인이 임의로 구성된 자격 증명 타입을 요청하지 못하게 해요.
호스트 기반 연결 조회
호스트 기반 타입은 URL을 포함한 쿼리를 받아요. 서비스는 URL을 파싱하고 일치하는 host를 가진 연결을 선택해요:
const connection = await connections.find({ type: 'github', query: { url: 'https://github.com/backstage/backstage', }, authMethods: ['token'],});connection.host; // stringconnection.auth.method; // 'token'connection.auth.token; // string
리터럴 type과 authMethods 값이 TypeScript 추론을 구동해요. 이 예시에서 결과는 GitHub 연결이며 connection.auth는 토큰 인증 형태로 좁혀져요.
인증 값은 만료될 수 있음
ConnectionsService.find는 정적 구성 또는 부트스트랩 자료를 반환해요. 반환된 토큰이 유효한지 확인하거나, 만료를 추적하거나, 갱신하지 않아요. 인증 메서드에 동적 수명 주기가 있을 때는 별도의 자격 증명 공급자를 사용하세요. 연결 서비스 제한 사항 을 참고하세요.
authMethods는 소비자가 처리하도록 구현된 인증 메서드의 비어 있지 않은 목록이에요. 폴백 선호도 목록이 아니에요. 연결 타입이 먼저 인증 항목을 선택하고, 서비스는 선택된 메서드가 소비자가 지원하는지 확인해요.
둘 이상의 인증 메서드 처리
코드가 처리할 수 있는 모든 메서드를 나열한 다음 connection.auth.method를 사용해 반환된 판별적(discriminated) 유니언을 좁히세요:
const connection = await connections.find({ type: 'github', query: { url: repositoryUrl }, authMethods: ['token', 'app'],});switch (connection.auth.method) { case 'token': return createClientWithToken({ host: connection.host, token: connection.auth.token, }); case 'app': return createClientWithGitHubApp({ host: connection.host, appId: connection.auth.appId, privateKey: connection.auth.privateKey, clientId: connection.auth.clientId, clientSecret: connection.auth.clientSecret, });}
애플리케이션 필드는 정적 자격 증명이지 설치 토큰이 아니에요. createClientWithGitHubApp 계층은 연결 서비스와 분리되어 있으며 토큰 교환과 캐싱을 담당해요.
AWS 계정 조회
aws 타입은 계정 번호, ARN, 또는 둘 다를 받아요:
const connection = await connections.find({ type: 'aws', query: { arn: 'arn:aws:iam::123456789012:role/BackstageReadRole', }, authMethods: ['account'],});connection.auth.method; // 'account'connection.auth.accountId; // string | undefinedconnection.auth.roleName; // string | undefined
AWS 연결 타입은 ARN에서 계정 번호를 파생하고, 정확한 계정 항목이 있으면 그것을 선택해요. 그렇지 않으면 구성된 경우 mainAccount로 표시된 항목을 반환해요.
연결을 받는 타입 함수
헬퍼, 클라이언트 팩토리, 또는 자격 증명 공급자가 서비스나 해결된 연결을 받을 때는 @backstage/connections의 공용 계약을 사용하세요:
import type { Connection, ConnectionsService } from '@backstage/connections';export async function findGitHubToken( connections: ConnectionsService, repositoryUrl: string,): Promise<Connection<'github', 'token'>> { return connections.find({ type: 'github', query: { url: repositoryUrl }, authMethods: ['token'], });}
유용한 공용 헬퍼는 다음과 같아요:
| 타입 | 목적 |
| ConnectionsService | 플러그인 범위 조회 서비스를 타입화. |
| Connection<TType, TAuthMethod> | 해결된 연결을 타입화하고 선택적으로 선택된 인증 메서드를 좁힘. |
| ConnectionTypeKey | 내장 타입 키의 유니언. |
| ConnectionAuthMethodKey<TType> | 한 타입의 인증 메서드 유니언. |
| LookupConnectionType<T> | 타입 키를 연결 타입 디스크립터로 해결. |
| ConnectionAuthValue<TAuthConfig> | 프레임워크 제공 인증 제목을 인증 구성 형태에 추가. |
공급자별 연결 형태를 플러그인 패키지에 복사하는 것보다 이러한 공유 타입을 선호하세요.
조회 오류 처리
find는 사용 가능한 연결을 반환할 수 없을 때 거부해요. 플러그인이 복구할 수 있는 결과만 처리하세요:
import { InputError, NotAllowedError, NotFoundError } from '@backstage/errors';try { const connection = await connections.find({ type: 'gitlab', query: { url: repositoryUrl }, authMethods: ['token'], }); return createGitLabClient(connection);} catch (error) { if (error instanceof NotFoundError) { logger.info(`No GitLab connection matches ${repositoryUrl}`); return undefined; } if (error instanceof NotAllowedError) { throw new InputError( 'The GitLab connection does not provide an authentication method this plugin supports', ); } throw error;}
선언되지 않은 연결 오류를 일반적인 부재로 잡지 마세요. 플러그인이나 모듈 등록에 누락된 선언을 추가하세요.
연결 데이터를 백엔드에 유지
해결된 연결은 시크릿을 포함할 수 있어요. 선택된 메서드가 none인 경우에도 반환된 객체를 민감하게 취급하세요:
-
전체 연결이나 인증 값을 기록하지 마세요.
-
백엔드 HTTP 라우트를 통해 연결 객체를 반환하지 마세요.
-
서비스를 프론트엔드 플러그인에 직접 노출하지 마세요.
-
클라이언트나 자격 증명 공급자가 요구하는 최소 필드만 전달하세요.
-
각 자격 증명에 부여된 권한을 외부 시스템이 강제하게 하세요.
알려진 자격 증명 공급자
일부 인증 메서드는 자격 증명 공급자가 사용 가능한 단기 자격 증명으로 교환해야 하는 부트스트랩 자료를 반환해요. 아래 표는 이 단계를 필요로 하는 내장 메서드와 공급자의 책임을 나열해요.
| 공급자 | 연결 타입 | 인증 메서드 | 공급자가 하는 일 |
| GitHub App | github | app | 애플리케이션 ID와 개인 키를 설치 토큰으로 교환하고 수명 동안 캐시. |
| AWS STS | aws, aws-codecommit, aws-s3 | account(with roleName), assumeRole | STS를 통해 역할을 수임해 임시 세션 자격 증명을 얻고 만료 전에 갱신. |
| Azure / Entra ID 클라이언트 자격 증명 | azure, azure-blob-storage | clientCredentials, aadCredential | Entra ID에 대해 OAuth 2.0 클라이언트 자격 증명 토큰 교환 수행. |
| Azure 관리 ID | azure | managedIdentity | 실행 중인 호스트가 사용할 수 있는 관리 ID 엔드포인트에서 토큰 획득. |
| Bitbucket Cloud OAuth | bitbucket-cloud | oauth | 클라이언트 ID와 시크릿을 OAuth 2.0 액세스 토큰으로 교환. |
| Google Cloud 서비스 계정 | google-gcs | serviceAccount | 서비스 계정 키에서 JWT를 서명하고 Google 액세스 토큰으로 교환. |
token, basic, pat, accessKey, accountKey 같은 여기에 나열되지 않은 인증 메서드는 중간 교환 단계 없이 직접 사용 가능한 자격 증명을 반환해요.
구성 및 범위 지정 예시는 연결 구성 및 관리 를 참고하세요.