-
Notifications
You must be signed in to change notification settings - Fork 288
fix: respect customized OIDC subject claims in azd pipeline config #7551
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
e3fe6b1
f08738e
549fad0
a71691a
3a7b1c3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -46,6 +46,10 @@ type GitHubCli interface { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CreatePrivateRepository(ctx context.Context, name string) error | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| GetGitProtocolType(ctx context.Context) (string, error) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| GitHubActionsExists(ctx context.Context, repoSlug string) (bool, error) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // GetOIDCSubjectForRepo returns the OIDC subject claim format for a repo by querying | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // the GitHub OIDC customization API. If the org/repo uses a custom subject template, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // the returned OIDCSubjectConfig will have UseDefault=false and IncludeClaimKeys set. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| GetOIDCSubjectForRepo(ctx context.Context, repoSlug string) (*OIDCSubjectConfig, error) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func NewGitHubCli(ctx context.Context, console input.Console, commandRunner exec.CommandRunner) (GitHubCli, error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -311,6 +315,103 @@ func (cli *ghCli) GitHubActionsExists(ctx context.Context, repoSlug string) (boo | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return true, nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // OIDCSubjectConfig represents the OIDC subject claim customization for a GitHub repository or org. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type OIDCSubjectConfig struct { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| UseDefault bool `json:"use_default"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| IncludeClaimKeys []string `json:"include_claim_keys"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // gitHubRepoInfo holds GitHub API repo metadata needed for OIDC subject construction. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type gitHubRepoInfo struct { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ID int `json:"id"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Owner struct { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ID int `json:"id"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } `json:"owner"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // BuildOIDCSubject constructs the correct OIDC subject claim for a federated identity credential. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // If the org/repo uses custom claim keys (e.g. repository_owner_id, repository_id), this function | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // queries the GitHub API for the numeric IDs and builds the subject accordingly. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // The suffix is the trailing part of the subject, e.g. "ref:refs/heads/main" or "pull_request". | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func BuildOIDCSubject( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ctx context.Context, cli GitHubCli, repoSlug string, oidcConfig *OIDCSubjectConfig, suffix string, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) (string, error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if oidcConfig == nil || oidcConfig.UseDefault { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return fmt.Sprintf("repo:%s:%s", repoSlug, suffix), nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+339
to
+341
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [MEDIUM] If the API returns
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // For custom claim templates, we need the repo and owner numeric IDs | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ghCliImpl, ok := cli.(*ghCli) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if !ok { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Fallback to default if we can't access the underlying CLI | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return fmt.Sprintf("repo:%s:%s", repoSlug, suffix), nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+336
to
+348
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| runArgs := ghCliImpl.newRunArgs("api", "/repos/"+repoSlug, "--jq", "{id: .id, owner: {id: .owner.id}}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| res, err := ghCliImpl.run(ctx, runArgs) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return "", fmt.Errorf("failed to get repository info for %s: %w", repoSlug, err) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var repoInfo gitHubRepoInfo | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err := json.Unmarshal([]byte(res.Stdout), &repoInfo); err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return "", fmt.Errorf("failed to parse repository info for %s: %w", repoSlug, err) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Build subject from claim keys | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // The claim keys define the parts before the context (ref/pull_request). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Example: include_claim_keys=["repository_owner_id", "repository_id"] produces | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // "repository_owner_id:123:repository_id:456:ref:refs/heads/main" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var parts []string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for _, key := range oidcConfig.IncludeClaimKeys { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| switch key { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case "repository_owner_id": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parts = append(parts, fmt.Sprintf("repository_owner_id:%d", repoInfo.Owner.ID)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case "repository_id": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parts = append(parts, fmt.Sprintf("repository_id:%d", repoInfo.ID)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case "repository_owner": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| owner := strings.SplitN(repoSlug, "/", 2) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parts = append(parts, fmt.Sprintf("repository_owner:%s", owner[0])) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case "repository": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parts = append(parts, fmt.Sprintf("repository:%s", repoSlug)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| default: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Unknown claim key — include it literally for forward compatibility | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parts = append(parts, key) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+375
to
+377
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [HIGH] Unknown claim keys get appended as bare names without values. Return an error so the user knows azd needs updating:
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parts = append(parts, suffix) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return strings.Join(parts, ":"), nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+318
to
+382
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // GetOIDCSubjectForRepo queries the GitHub OIDC customization API for a repository. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // It first checks the repo-level customization, then falls back to the org-level customization. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // If no customization is found (or the API returns 404), it returns a config with UseDefault=true. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (cli *ghCli) GetOIDCSubjectForRepo(ctx context.Context, repoSlug string) (*OIDCSubjectConfig, error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Try repo-level first | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| runArgs := cli.newRunArgs("api", "/repos/"+repoSlug+"/actions/oidc/customization/sub") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| res, err := cli.run(ctx, runArgs) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err == nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var config OIDCSubjectConfig | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if jsonErr := json.Unmarshal([]byte(res.Stdout), &config); jsonErr == nil && !config.UseDefault { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return &config, nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Fall back to org-level | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| parts := strings.SplitN(repoSlug, "/", 2) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if len(parts) == 2 { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| orgRunArgs := cli.newRunArgs("api", "/orgs/"+parts[0]+"/actions/oidc/customization/sub") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| orgRes, orgErr := cli.run(ctx, orgRunArgs) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if orgErr == nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var config OIDCSubjectConfig | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if jsonErr := json.Unmarshal([]byte(orgRes.Stdout), &config); jsonErr == nil && !config.UseDefault { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return &config, nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Default: no customization | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+384
to
+411
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // GetOIDCSubjectForRepo queries the GitHub OIDC customization API for a repository. | |
| // It first checks the repo-level customization, then falls back to the org-level customization. | |
| // If no customization is found (or the API returns 404), it returns a config with UseDefault=true. | |
| func (cli *ghCli) GetOIDCSubjectForRepo(ctx context.Context, repoSlug string) (*OIDCSubjectConfig, error) { | |
| // Try repo-level first | |
| runArgs := cli.newRunArgs("api", "/repos/"+repoSlug+"/actions/oidc/customization/sub") | |
| res, err := cli.run(ctx, runArgs) | |
| if err == nil { | |
| var config OIDCSubjectConfig | |
| if jsonErr := json.Unmarshal([]byte(res.Stdout), &config); jsonErr == nil && !config.UseDefault { | |
| return &config, nil | |
| } | |
| } | |
| // Fall back to org-level | |
| parts := strings.SplitN(repoSlug, "/", 2) | |
| if len(parts) == 2 { | |
| orgRunArgs := cli.newRunArgs("api", "/orgs/"+parts[0]+"/actions/oidc/customization/sub") | |
| orgRes, orgErr := cli.run(ctx, orgRunArgs) | |
| if orgErr == nil { | |
| var config OIDCSubjectConfig | |
| if jsonErr := json.Unmarshal([]byte(orgRes.Stdout), &config); jsonErr == nil && !config.UseDefault { | |
| return &config, nil | |
| } | |
| } | |
| } | |
| // Default: no customization | |
| func isGitHubNotFoundError(err error) bool { | |
| if err == nil { | |
| return false | |
| } | |
| errText := strings.ToLower(err.Error()) | |
| return strings.Contains(errText, "404") || strings.Contains(errText, "not found") | |
| } | |
| // GetOIDCSubjectForRepo queries the GitHub OIDC customization API for a repository. | |
| // It first checks the repo-level customization, then falls back to the org-level customization. | |
| // If no customization is found (or the API returns 404), it returns a config with UseDefault=true. | |
| func (cli *ghCli) GetOIDCSubjectForRepo(ctx context.Context, repoSlug string) (*OIDCSubjectConfig, error) { | |
| // Try repo-level first. | |
| runArgs := cli.newRunArgs("api", "/repos/"+repoSlug+"/actions/oidc/customization/sub") | |
| res, err := cli.run(ctx, runArgs) | |
| if err == nil { | |
| var config OIDCSubjectConfig | |
| if jsonErr := json.Unmarshal([]byte(res.Stdout), &config); jsonErr != nil { | |
| return nil, jsonErr | |
| } | |
| return &config, nil | |
| } | |
| if !isGitHubNotFoundError(err) { | |
| return nil, err | |
| } | |
| // Fall back to org-level only when the repo-level customization is not found. | |
| parts := strings.SplitN(repoSlug, "/", 2) | |
| if len(parts) == 2 { | |
| orgRunArgs := cli.newRunArgs("api", "/orgs/"+parts[0]+"/actions/oidc/customization/sub") | |
| orgRes, orgErr := cli.run(ctx, orgRunArgs) | |
| if orgErr == nil { | |
| var config OIDCSubjectConfig | |
| if jsonErr := json.Unmarshal([]byte(orgRes.Stdout), &config); jsonErr != nil { | |
| return nil, jsonErr | |
| } | |
| return &config, nil | |
| } | |
| if !isGitHubNotFoundError(orgErr) { | |
| return nil, orgErr | |
| } | |
| } | |
| // Default: no customization. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,11 +7,22 @@ param storage object | |
| param administratorLogin string | ||
| @secure() | ||
| param administratorLoginPassword string | ||
| param activeDirectoryAuth string = 'Disabled' | ||
| param databaseNames array = [] | ||
| param allowAzureIPsFirewall bool = false | ||
| param allowAllIPsFirewall bool = false | ||
| param allowedSingleIPs array = [] | ||
|
|
||
| param highAvailabilityMode string = 'Disabled' | ||
|
|
||
| param backupRetentionDays int = 7 | ||
| param geoRedundantBackup string = 'Disabled' | ||
|
|
||
| param maintenanceWindowCustomWindow string = 'Disabled' | ||
| param maintenanceWindowDayOfWeek int = 0 | ||
| param maintenanceWindowStartHour int = 0 | ||
| param maintenanceWindowStartMinute int = 0 | ||
|
|
||
| // PostgreSQL version | ||
| param version string | ||
|
|
||
|
|
@@ -27,7 +38,21 @@ resource postgresServer 'Microsoft.DBforPostgreSQL/flexibleServers@2022-12-01' = | |
| administratorLoginPassword: administratorLoginPassword | ||
| storage: storage | ||
| highAvailability: { | ||
| mode: 'Disabled' | ||
| mode: highAvailabilityMode | ||
| } | ||
| authConfig: { | ||
| activeDirectoryAuth: activeDirectoryAuth | ||
| passwordAuth: (administratorLoginPassword == null) ? 'Disabled' : 'Enabled' | ||
| } | ||
|
Comment on lines
+43
to
+46
|
||
| backup: { | ||
| backupRetentionDays: backupRetentionDays | ||
| geoRedundantBackup: geoRedundantBackup | ||
| } | ||
| maintenanceWindow: { | ||
| customWindow: maintenanceWindowCustomWindow | ||
| dayOfWeek: maintenanceWindowDayOfWeek | ||
| startHour: maintenanceWindowStartHour | ||
| startMinute: maintenanceWindowStartMinute | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -38,24 +63,24 @@ resource postgresServer 'Microsoft.DBforPostgreSQL/flexibleServers@2022-12-01' = | |
| resource firewall_all 'firewallRules' = if (allowAllIPsFirewall) { | ||
| name: 'allow-all-IPs' | ||
| properties: { | ||
| startIpAddress: '0.0.0.0' | ||
| endIpAddress: '255.255.255.255' | ||
| startIpAddress: '0.0.0.0' | ||
| endIpAddress: '255.255.255.255' | ||
| } | ||
| } | ||
|
|
||
| resource firewall_azure 'firewallRules' = if (allowAzureIPsFirewall) { | ||
| name: 'allow-all-azure-internal-IPs' | ||
| properties: { | ||
| startIpAddress: '0.0.0.0' | ||
| endIpAddress: '0.0.0.0' | ||
| startIpAddress: '0.0.0.0' | ||
| endIpAddress: '0.0.0.0' | ||
| } | ||
| } | ||
|
|
||
| resource firewall_single 'firewallRules' = [for ip in allowedSingleIPs: { | ||
| name: 'allow-single-${replace(ip, '.', '')}' | ||
| properties: { | ||
| startIpAddress: ip | ||
| endIpAddress: ip | ||
| startIpAddress: ip | ||
| endIpAddress: ip | ||
| } | ||
| }] | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,6 +33,7 @@ param numberOfWorkers int = -1 | |
| param scmDoBuildDuringDeployment bool = false | ||
| param use32BitWorkerProcess bool = false | ||
| param ftpsState string = 'FtpsOnly' | ||
| param httpLoggingEnabled bool = false | ||
| param healthCheckPath string = '' | ||
|
|
||
| resource appService 'Microsoft.Web/sites@2022-03-01' = { | ||
|
|
@@ -46,6 +47,7 @@ resource appService 'Microsoft.Web/sites@2022-03-01' = { | |
| linuxFxVersion: linuxFxVersion | ||
| alwaysOn: alwaysOn | ||
| ftpsState: ftpsState | ||
| httpLoggingEnabled: httpLoggingEnabled | ||
|
Comment on lines
33
to
+50
|
||
| appCommandLine: appCommandLine | ||
| numberOfWorkers: numberOfWorkers != -1 ? numberOfWorkers : null | ||
| minimumElasticInstanceCount: minimumElasticInstanceCount != -1 ? minimumElasticInstanceCount : null | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BuildOIDCSubject is invoked twice (for main + pull_request). When a repo uses custom claim keys, each call performs its own
gh api /repos/{slug}request to fetch IDs, resulting in duplicate network/CLI calls duringazd pipeline config. Consider fetching repo info once and reusing it (e.g., have GetOIDCSubjectForRepo also return the needed IDs, or add a helper that builds both subjects from a single repo lookup).