apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  annotations:
    auth.upbound.io/config: |
      version: "2023-06-23"
      discriminant: spec.credentials.source
      sources:
      - name: Upbound
        docs: |
          # Upbound OpenID Connect (OIDC)

          Using Upbound OIDC to authenticate to Azure eliminates the need to store credentials in this control plane.

          You will need to:

          1. Create an **Azure Application** that will be used to authenticate `provider-azure`.
          2. Establish trust between your **Azure Application** and **Upbound** using a **Federated Credential**.
          3. Grant the necessary permissions to your **Application Service Principal** by assigning it a **Role**.
          4. Provide **Client ID**, **Tenant ID**, and **Subscription ID** of your **Azure Application**.

          ## Create an Application

          1. Sign in to [Azure portal](https://portal.azure.com/).
          2. Go to **Azure Active Directory**.
          3. Select **App registrations** in the left navigation.
          4. Click **+ New registration**.
          5. In the **Name** field enter `upbound-oidc-provider`.
          6. In the **Supported account types**> section select **Accounts in this organizational directory only**.
          7. In the **Redirect URI** section select **Web** and leave the **URL** field blank.
          8. Press **Register**.

          ## Create a Federated Credential

          When **Upbound** authenticates to **Azure** it provides an OIDC subject (`sub`) in the following format:
          ```
          mcp:<account>/<mcp-name>:provider:<provider-name>
          ```
          We will create a **Federated Credential** to establish trust between **Azure** and **Upbound**.

          1. Sign in to [Azure portal](https://portal.azure.com/).
          2. Go to **Azure Active Directory**.
          3. Select **App registrations** in the left navigation.
          4. Select your **Application** by searching for `upbound-oidc-provider`.
          5. Select **Certificates and secrets** in the left navigation.
          6. Select **Federated credentials** tab.
          7. Click **+ Add credential**.
          8. In **Federated credential scenario** select `Other Issuer`.
          9. Fill out **Connect your account** with the following:
                * **Issuer**: `https://proidc.upbound.io`.
                * **Subject identifier**: `mcp:<account>/<mcp-name>:provider:provider-azure`.
          10. Fill out **Credential details** with the following:
                * **Name**: `upbound-<account>-<mcp-name>-provider-azure`.
                * **Description**: `Upbound MCP <account>/<mcp-name> Provider Azure`.
                * **Audience**: leave unmodified with`api://AzureADTokenExchange`.
          11. Press **Add**.

          ## Assign a Role to the Application Service Principal

          1. Sign in to [Azure portal](https://portal.azure.com/).
          2. Go to **Subscriptions**.
          3. Select your subscription.
          4. Select **Access control (IAM)** in the left navigation.
          5. Click **+ Add** and select **Add role assignment**.
          6. Select **Privileged administrator roles** tab.
          7. Find and select the `Contributor` role.
          8. Press **Next**.
          9. In **Assign access to** select **User, group, or service principal**.
          10. Click **+ Select members**.
          11. Find your application by entering `upbound-oidc-provider` in the search field.
          12. Press **Select**.
          13. Press **Review + assign**.
          14. Make sure everything is correct and press **Review + assign** again.

          ## Find your Client ID, Tenant ID, and Subscription ID

          ### Find your Client ID, Tenant ID

          1. Sign in to [Azure portal](https://portal.azure.com/).
          2. Go to **Azure Active Directory**.
          3. Select **App registrations** in the left navigation.
          4. Select your **Application** by searching for `upbound-oidc-provider`.
          5. Select **Overview** in the left navigation.
          6. Copy **Application (client) ID** and paste it as **Client ID** in the **Upbound** UI.

          ### Find your Subscription ID

          1. Sign in to [Azure portal](https://portal.azure.com/).
          2. Go to **Subscriptions**.
          3. Select your subscription.
          4. Copy **Subscription ID** and paste it as **Subscription ID** in the **Upbound** UI.
        additionalResources: []
        showFields:
        - spec.clientID
        - spec.tenantID
        - spec.subscriptionID
    controller-gen.kubebuilder.io/version: v0.14.0
    kustomize.config.k8s.io/id: |
      group: apiextensions.k8s.io
      kind: CustomResourceDefinition
      name: providerconfigs.azure.upbound.io
      version: v1
  name: providerconfigs.azure.upbound.io
spec:
  conversion:
    strategy: Webhook
    webhook:
      clientConfig:
        caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUQrakNDQXVLZ0F3SUJBZ0lDQitZd0RRWUpLb1pJaHZjTkFRRUxCUUF3V2pFT01Bd0dBMVVFQmhNRlJXRnkKZEdneERqQU1CZ05WQkFnVEJVVmhjblJvTVE0d0RBWURWUVFIRXdWRllYSjBhREVUTUJFR0ExVUVDaE1LUTNKdgpjM053YkdGdVpURVRNQkVHQTFVRUF4TUtRM0p2YzNOd2JHRnVaVEFlRncweU5ERXhNalV3T0RJNU5UVmFGdzB6Ck5ERXhNalV3T0RJNU5UVmFNRm94RGpBTUJnTlZCQVlUQlVWaGNuUm9NUTR3REFZRFZRUUlFd1ZGWVhKMGFERU8KTUF3R0ExVUVCeE1GUldGeWRHZ3hFekFSQmdOVkJBb1RDa055YjNOemNHeGhibVV4RXpBUkJnTlZCQU1UQ2tOeQpiM056Y0d4aGJtVXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFETkx3MW5xNnd2Ci9GVUNXOUtYa2s4NnRhZ2lZSE54dXorSjhvS1l5NTVUenZqaVBrMzEzdzI4UUlpRmNWRTdkdm1wQm9scFRiNC8KMzNydjFwWkFSOEZQVFF4NkVLeTBmMnZOYVJxenBRbUU2SGF4QUZwM2VESVJWUGpHR2piYXlzTEp0Mjk3TmdzbApBdkpVdHcrbXlhNms5aVlPMnhvL0lYbnNmOXdHTXJQcnF1NURsWWlsRllERW8wblovbEdlTVVFVjMwOUd6VzRCCkJvZzJYS09WdUtOV3NuZkJaUkhOb1JqbWovMFVickRWcmxDMk9mWnJTaDMwVHg3VVJ3LzVpVUpibU5tWW1OYXgKTVhkZzRyR280MjN5aTk2RU5zVHJGRE9jaXlOdWpMUUxFTjQ3WExHMnpnY2dKc09FVis5Zng3L3J0UW9sK01GRwpGdkdoUXJFN25kWDFBZ01CQUFHamdja3dnY1l3RGdZRFZSMFBBUUgvQkFRREFnU3dNQk1HQTFVZEpRUU1NQW9HCkNDc0dBUVVGQndNQk1Bd0dBMVVkRXdFQi93UUNNQUF3Z1pBR0ExVWRFUVNCaURDQmhZSWRkWEJpYjNWdVpDMXcKY205MmFXUmxjaTFtWVcxcGJIa3RZWHAxY21XQ0wzVndZbTkxYm1RdGNISnZkbWxrWlhJdFptRnRhV3g1TFdGNgpkWEpsTG1OeWIzTnpjR3hoYm1VdGMzbHpkR1Z0Z2pOMWNHSnZkVzVrTFhCeWIzWnBaR1Z5TFdaaGJXbHNlUzFoCmVuVnlaUzVqY205emMzQnNZVzVsTFhONWMzUmxiUzV6ZG1Nd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFJK1kKckJYUHNWUklDOThrRjdBcUhtQmd2cDREa3phWTRueVN4V2loOUw1WUZHZ1N2c0FzMnZ4NnM3TTViU3JxTlljQgpwZmlxQmt2eHd5cTZLeVZDNE5JUjRSRzd6Y1huTDFKS2FmSU93TnFiR3d3T0RrcVRrOXRpOS96b09BK3puS2xoCmw1VjhCUUt4dHhJQjltVExYaTZJdmNmQmlrdGp3QmZ3VHA1Ym80TVZ5clBRblhRamp0dnJFa3pnc3JFM1ZYZ1IKekU0eDFPdFQ4b2JiUnZxSGhNbWdTUUlWVFRvTmc4RTdMM1RJTWdJMytKeHk1YWhqcDV6WVBOQmRWWEhMVVBhagpzczA3UHM0YXBvNUI5OTdvK05uNzdWQ2MzV2NQaVhsQXpHKzRPaXdlZzJtUmpsTmtsUGw4NU5pQnRMQi83VFVZCkppbkRSZ1ZVNWtOaDJQL2VSMDQ9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
        service:
          name: upbound-provider-family-azure
          namespace: crossplane-system
          path: /convert
          port: 9443
      conversionReviewVersions:
      - v1
  group: azure.upbound.io
  names:
    categories:
    - crossplane
    - providerconfig
    - azure
    kind: ProviderConfig
    listKind: ProviderConfigList
    plural: providerconfigs
    singular: providerconfig
  scope: Cluster
  versions:
  - additionalPrinterColumns:
    - jsonPath: .metadata.creationTimestamp
      name: AGE
      type: date
    - jsonPath: .spec.credentials.secretRef.name
      name: SECRET-NAME
      priority: 1
      type: string
    name: v1beta1
    schema:
      openAPIV3Schema:
        description: A ProviderConfig configures the Azure provider.
        properties:
          apiVersion:
            description: |-
              APIVersion defines the versioned schema of this representation of an object.
              Servers should convert recognized schemas to the latest internal value, and
              may reject unrecognized values.
              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
            type: string
          kind:
            description: |-
              Kind is a string value representing the REST resource this object represents.
              Servers may infer this from the endpoint the client submits requests to.
              Cannot be updated.
              In CamelCase.
              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
            type: string
          metadata:
            type: object
          spec:
            description: A ProviderConfigSpec defines the desired state of a ProviderConfig.
            properties:
              clientID:
                description: |-
                  ClientID is the user-assigned managed identity's ID
                  when Credentials.Source is `InjectedIdentity`. If unset and
                  Credentials.Source is `InjectedIdentity`, then a system-assigned
                  managed identity is used.
                type: string
              credentials:
                description: Credentials required to authenticate to this provider.
                properties:
                  env:
                    description: |-
                      Env is a reference to an environment variable that contains credentials
                      that must be used to connect to the provider.
                    properties:
                      name:
                        description: Name is the name of an environment variable.
                        type: string
                    required:
                    - name
                    type: object
                  fs:
                    description: |-
                      Fs is a reference to a filesystem location that contains credentials that
                      must be used to connect to the provider.
                    properties:
                      path:
                        description: Path is a filesystem path.
                        type: string
                    required:
                    - path
                    type: object
                  secretRef:
                    description: |-
                      A SecretRef is a reference to a secret key that contains the credentials
                      that must be used to connect to the provider.
                    properties:
                      key:
                        description: The key to select.
                        type: string
                      name:
                        description: Name of the secret.
                        type: string
                      namespace:
                        description: Namespace of the secret.
                        type: string
                    required:
                    - key
                    - name
                    - namespace
                    type: object
                  source:
                    description: Source of the provider credentials.
                    enum:
                    - None
                    - Secret
                    - UserAssignedManagedIdentity
                    - SystemAssignedManagedIdentity
                    - OIDCTokenFile
                    - Upbound
                    - Filesystem
                    type: string
                required:
                - source
                type: object
              environment:
                description: |-
                  The Cloud Environment which should be used. Possible values are "public",
                  "usgovernment", "german", and "china". Defaults to "public".
                type: string
              msiEndpoint:
                description: |-
                  MSIEndpoint is the optional path to a custom endpoint for
                  Managed Service Identity.
                type: string
              oidcTokenFilePath:
                description: |-
                  OIDCTokenFilePath is the optional path to a token file
                  that allows to access a managed identity.
                type: string
              subscriptionID:
                description: |-
                  SubscriptionID is the Azure subscription ID to be used.
                  If unset, subscription ID from Credentials will be used.
                  Required if Credentials.Source is InjectedIdentity.
                type: string
              tenantID:
                description: |-
                  TenantID is the Azure AD tenant ID to be used.
                  If unset, tenant ID from Credentials will be used.
                  Required if Credentials.Source is InjectedIdentity.
                type: string
            required:
            - credentials
            type: object
          status:
            description: A ProviderConfigStatus reflects the observed state of a ProviderConfig.
            properties:
              conditions:
                description: Conditions of the resource.
                items:
                  description: A Condition that may apply to a resource.
                  properties:
                    lastTransitionTime:
                      description: |-
                        LastTransitionTime is the last time this condition transitioned from one
                        status to another.
                      format: date-time
                      type: string
                    message:
                      description: |-
                        A Message containing details about this condition's last transition from
                        one status to another, if any.
                      type: string
                    observedGeneration:
                      description: |-
                        ObservedGeneration represents the .metadata.generation that the condition was set based upon.
                        For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
                        with respect to the current state of the instance.
                      format: int64
                      type: integer
                    reason:
                      description: A Reason for this condition's last transition from
                        one status to another.
                      type: string
                    status:
                      description: Status of this condition; is it currently True,
                        False, or Unknown?
                      type: string
                    type:
                      description: |-
                        Type of this condition. At most one of each condition type may apply to
                        a resource at any point in time.
                      type: string
                  required:
                  - lastTransitionTime
                  - reason
                  - status
                  - type
                  type: object
                type: array
                x-kubernetes-list-map-keys:
                - type
                x-kubernetes-list-type: map
              users:
                description: Users of this provider configuration.
                format: int64
                type: integer
            type: object
        required:
        - spec
        type: object
    served: true
    storage: true
    subresources:
      status: {}
