(ctx context.Context, providerURL string, tokenString string)
| 74 | } |
| 75 | |
| 76 | func parseToken(ctx context.Context, providerURL string, tokenString string) (*GitlabToken, error) { |
| 77 | provider, err := oidc.NewProvider(ctx, providerURL) |
| 78 | if err != nil { |
| 79 | return nil, fmt.Errorf("failed to connect to OIDC provider: %w", err) |
| 80 | } |
| 81 | |
| 82 | verifier := provider.Verifier(&oidc.Config{ |
| 83 | SkipClientIDCheck: true, // Skip client ID check since we're just parsing |
| 84 | }) |
| 85 | |
| 86 | idToken, err := verifier.Verify(ctx, tokenString) |
| 87 | if err != nil { |
| 88 | return nil, fmt.Errorf("token verification failed: %w", err) |
| 89 | } |
| 90 | |
| 91 | token := &GitlabToken{ |
| 92 | IDToken: *idToken, |
| 93 | RawToken: tokenString, |
| 94 | } |
| 95 | |
| 96 | // Verify the audience |
| 97 | if !slices.Contains(idToken.Audience, ExpectedAudience) { |
| 98 | return nil, fmt.Errorf("invalid audience: expected %q", ExpectedAudience) |
| 99 | } |
| 100 | |
| 101 | // Extract claims to populate our custom fields |
| 102 | var claims map[string]interface{} |
| 103 | if err := idToken.Claims(&claims); err != nil { |
| 104 | return nil, fmt.Errorf("failed to extract claims: %w", err) |
| 105 | } |
| 106 | |
| 107 | if configRefURI, ok := claims["ci_config_ref_uri"].(string); ok { |
| 108 | token.ConfigRefURI = configRefURI |
| 109 | } |
| 110 | |
| 111 | if runnerEnv, ok := claims["runner_environment"].(string); ok { |
| 112 | token.RunnerEnvironment = runnerEnv |
| 113 | } |
| 114 | |
| 115 | return token, nil |
| 116 | } |
| 117 | |
| 118 | // To load the auth token we do it in two steps: |
| 119 | // 1 - check if it's explicitly set as an environment variable GITLAB_OIDC |
no test coverage detected