mirror of
https://github.com/versity/versitygw.git
synced 2026-09-25 01:14:22 +00:00
feat: add IAM OIDC provider CRUD
Add support for `CreateOpenIDConnectProvider`, `GetOpenIDConnectProvider`, `ListOpenIDConnectProviders`, `DeleteOpenIDConnectProvider`, `AddClientIDToOpenIDConnectProvider`, `RemoveClientIDFromOpenIDConnectProvider`, and `UpdateOpenIDConnectProviderThumbprint` on both the internal and Vault storage backends, rounding out the standalone IAM service with the same OIDC identity provider management AWS IAM exposes. CreateOpenIDConnectProvider validates the issuer URL, enforces the client ID and per-provider client ID list limits, and accepts an optional ThumbprintList. When the caller omits ThumbprintList, the provider auto-fetches the thumbprint by opening an outbound TLS connection to the issuer URL and hashing its top-level CA certificate, matching real AWS behavior. This auto-fetch is configurable: it can be turned off with the `--disable-oidc-thumbprint-autofetch` CLI flag (or the `VGW_IAM_DISABLE_OIDC_THUMBPRINT_AUTOFETCH` environment variable) for restricted or air-gapped deployments where the IAM server shouldn't make outbound connections, in which case an omitted ThumbprintList is rejected instead. AddClientIDToOpenIDConnectProvider and RemoveClientIDFromOpenIDConnectProvider manage a provider's client ID list, and UpdateOpenIDConnectProviderThumbprint replaces its thumbprint list, all with the same length and format validation applied at creation time. Provider ARNs are derived from the issuer URL, and GetOpenIDConnectProvider and DeleteOpenIDConnectProvider resolve providers by ARN, returning NoSuchEntity when a provider doesn't exist. ListOpenIDConnectProviders returns the full set of stored providers. These actions are wired into the IAM API router and given their own XML response types under iamapi/types, with a new iamapi/internal/iamutil package handling URL validation, thumbprint fetching and normalization, and ARN construction shared across the controller methods.
This commit is contained in:
@@ -425,6 +425,10 @@ func ValueTooLong(field string, maxLength int) Error {
|
||||
return ValidationError(fmt.Sprintf("1 validation error detected: Value at '%s' failed to satisfy constraint: Member must have length less than or equal to %d", field, maxLength))
|
||||
}
|
||||
|
||||
func ValueTooShort(field string, minLength int) Error {
|
||||
return ValidationError(fmt.Sprintf("1 validation error detected: Value at '%s' failed to satisfy constraint: Member must have length greater than or equal to %d", field, minLength))
|
||||
}
|
||||
|
||||
func InvalidCharset(field string) Error {
|
||||
return ValidationError(fmt.Sprintf("The specified value for %s is invalid. It must contain only printable ASCII characters.", field))
|
||||
}
|
||||
@@ -461,6 +465,47 @@ func InlinePolicyQuotaExceeded(entityKind, entityName string, maxBytes int) Erro
|
||||
return newSenderError("LimitExceeded", fmt.Sprintf("Maximum policy size of %d bytes exceeded for %s %s", maxBytes, entityKind, entityName), http.StatusConflict)
|
||||
}
|
||||
|
||||
func EntityAlreadyExistsOIDCProvider(url string) Error {
|
||||
return newSenderError("EntityAlreadyExists", fmt.Sprintf("Provider with url %s already exists.", url), http.StatusConflict)
|
||||
}
|
||||
|
||||
func NoSuchEntityOIDCProviderGet(arn string) Error {
|
||||
return newSenderError("NoSuchEntity", fmt.Sprintf("OpenIDConnect Provider not found for arn %s", arn), http.StatusNotFound)
|
||||
}
|
||||
|
||||
func NoSuchEntityOIDCProviderDelete(arn string) Error {
|
||||
return newSenderError("NoSuchEntity", fmt.Sprintf("OpenId connect Provider %s cannot be found.", arn), http.StatusNotFound)
|
||||
}
|
||||
|
||||
// AccessDeniedOIDCProvider is returned when a well-formed OIDC provider ARN
|
||||
// references an account id other than callerAccountID.
|
||||
func AccessDeniedOIDCProvider(callerAccountID, resourceArn string) Error {
|
||||
return newSenderError("AccessDenied", fmt.Sprintf(
|
||||
"User: arn:aws:iam::%s:root is not authorized to perform this action on resource: %s",
|
||||
callerAccountID, resourceArn,
|
||||
), http.StatusForbidden)
|
||||
}
|
||||
|
||||
func ClientIdsPerOpenIdConnectProviderLimitExceeded(max int) Error {
|
||||
return newSenderError("LimitExceeded", fmt.Sprintf("Cannot exceed quota for ClientIdsPerOpenIdConnectProvider: %d", max), http.StatusConflict)
|
||||
}
|
||||
|
||||
func ThumbprintListTooLong(max int) Error {
|
||||
return newSenderError("InvalidInput", fmt.Sprintf("Thumbprint list must contain fewer than %d entries.", max), http.StatusBadRequest)
|
||||
}
|
||||
|
||||
func ThumbprintListEmpty() Error {
|
||||
return newSenderError("InvalidInput", "Thumbprint list must contain at least one entry.", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
func OIDCProvidersPerAccountLimitExceeded(max int) Error {
|
||||
return newSenderError("LimitExceeded", fmt.Sprintf("Cannot exceed quota for OpenIDConnectProvidersPerAccount: %d", max), http.StatusConflict)
|
||||
}
|
||||
|
||||
func OpenIdIdpCommunicationError(url string) Error {
|
||||
return newSenderError("OpenIdIdpCommunicationError", fmt.Sprintf("Could not connect to %s", url), http.StatusBadRequest)
|
||||
}
|
||||
|
||||
func newSenderError(code, message string, statusCode int) Error {
|
||||
return Error{
|
||||
Type: TypeSender,
|
||||
|
||||
Reference in New Issue
Block a user