Skip to content

Unable to create vault groupAlias using crossplane provider #683

@fabualnaja

Description

@fabualnaja

Description

identity.vault.upbound.io/v1alpha1 GroupAlias fails to create via RGD (instance ends in ERROR)

Summary:

When reconciling an RGD that creates Vault Group and Vault GroupAlias (both under identity.vault.upbound.io/v1alpha1), the Group is created successfully but the GroupAlias never gets created. The AppAccess instance ends in State=ERROR with:

failed to create resource: the server could not find the requested resource

This happens regardless of namespacing (both resources are cluster-scoped, and the failure persists even when metadata.namespace is omitted from the template).

Other resources in the graph (ArgoCD roles/bindings, Keycloak roles, Vault policy/group) reconcile fine.

Environment:

  • kro version: v0.4.1

  • Kubernetes:

    • Client: v1.32.3
    • Server: v1.28.15
  • Relevant providers/CRDs installed:

    • Crossplane version 1.20.0 (also I have tried v1.18.0 , v1.19.0, and 2.0.0)
    • Upbound Vault provider version 2.1.1 (identity.vault.upbound.io, vault.vault.upbound.io)
    • Keycloak Crossplane provider (role.keycloak.crossplane.io)
    • External Secrets Operator (external-secrets.io)

RGD

apiVersion: kro.run/v1alpha1
kind: ResourceGraphDefinition
metadata:
  name: appaccess
spec:
  schema:
    apiVersion: v1alpha1
    kind: AppAccess
    spec:
      appName: string
      argoNamespace: string | default="argocd-system"
      enableKeycloak: boolean | default=true
      enableVault: boolean | default=true
      enableExec: boolean | default=true
      enableView: boolean | default=true

      # Keycloak (Argo roles)
      keycloakProviderConfig: string | default="keycloak-provider-config"
      argoClientRefName: string | default="argo-cd-client"
      realm: string | default="master-realm"

      # Keycloak (Vault client) - enable flag + client name
      enableKeycloakVaultRoles: boolean | default=true
      vaultClientRefName: string | default="vault-client"

      # Vault / ESO
      vaultProviderConfig: string | default="vault-provider-config"
      vaultMountAccessor: string | default="<>"
      vaultSecretStore: string | default="vault-backend"
      vaultPlaceholderSecretName: string | default="vault-placeholder-secret"
      pushSecretApiVersion: string | default="external-secrets.io/v1alpha1"
      # vaultNamespace: string | default="vault"
      vaultKvMount: string | default="secrets"

  resources:
# shortend

    - id: vaultGroup
      includeWhen:
        - ${schema.spec.enableVault}
        - ${schema.spec.enableKeycloak}
      template:
        apiVersion: identity.vault.upbound.io/v1alpha1
        kind: Group
        metadata:
          name: ${schema.spec.appName}
        spec:
          forProvider:
            name: ${schema.spec.appName}
            policies:
              - ${vaultPolicy.spec.forProvider.name}
            type: external
          providerConfigRef:
            name: ${schema.spec.vaultProviderConfig}
    
    - id: vaultAlias
      includeWhen:
        - ${schema.spec.enableVault}
        - ${schema.spec.enableKeycloak}
      template:
        apiVersion: identity.vault.upbound.io/v1alpha1
        kind: GroupAlias
        metadata:
          name: ${schema.spec.appName}
        spec:
          forProvider:
            name: ${schema.spec.appName}
            canonicalIdRef:
              name: ${vaultGroup.metadata.name}
            # NOTE: also tried hardcoding mountAccessor and canonicalId;
            # failure persists with the same "server could not find the requested resource".

          providerConfigRef:
            name: ${schema.spec.vaultProviderConfig}

instance

apiVersion: kro.run/v1alpha1
kind: AppAccess
metadata:
  name: hello-backend-access
  namespace: default
spec:
  appName: hello-backend
  # RBAC
  enableExec: true
  enableView: true
  # Keycloak (Argo + Vault client roles)
  enableKeycloak: true
  # Vault + ESO
  enableVault: true

Status:

Status:
  Conditions:
    Last Transition Time:  2025-09-17T17:39:47Z
    Message:               failed to create resource: the server could not find the requested resource
    Reason:                ReconciliationFailed
    Status:                False
    Type:                  InstanceSynced
  State:                   ERROR

kro-controller logs:

2025-09-17T17:39:47.963Z  appaccesses-controller  Using resource-specified namespace  {"resourceID":"vaultAlias","namespace":"default"}
2025-09-17T17:39:47.964Z  appaccesses-controller  Creating new resource               {"resourceID":"vaultAlias"}

Managed resources present (no GroupAlias):

$ kubectl get managed -A | grep hello-backend 

group.identity.vault.upbound.io/hello-backend                 True     True    7c7c0029-ec6d-4141-57a5-589bc3064029   3m52s
role.role.keycloak.crossplane.io/argo-cd-hello-backend-admin-role                 True     True    07b68749-4c06-4eab-95bd-01e874e518c8   4m13s
role.role.keycloak.crossplane.io/argo-cd-hello-backend-exec-role                  True     True    ea987c17-0ff0-4a29-a689-56a89cde2500   4m9s
role.role.keycloak.crossplane.io/argo-cd-hello-backend-view-role                  True     True    15295671-85a0-42a3-8d39-197f79862e7c   4m6s
role.role.keycloak.crossplane.io/vault-hello-backend-role                         True     True    7de18f5c-37da-4573-a58e-dd43b56e9016   4m3s
policy.vault.vault.upbound.io/hello-backend                 True     True    hello-backend                 3m57s

Expected behavior

  • GroupAlias should be created via KRO just like Group and other resources specially that they share the same apiVersion.

Actual behavior

  • Instance ends in ERROR with failed to create resource: the server could not find the requested resource, and GroupAlias is never created—despite using the same apiGroup/version as Group.

Additional observations / things I tried

  • Hardcoded GroupAlias template with:
    • canonicalIdRef → failure
    • canonicalId (string) → failure
    • Explicit mountAccessor set → failure
  • Removing or adding metadata.namespace does not resolve it (scope appears unrelated; error text stays the same).

Minimal repro (tight)

apiVersion: kro.run/v1alpha1
kind: ResourceGraphDefinition
metadata:
  name: bug-repro
spec:
  schema:
    apiVersion: v1alpha1
    kind: Repro
    spec: { appName: string, vaultProviderConfig: string, mountAccessor: string }
  resources:
    - id: grp
      template:
        apiVersion: identity.vault.upbound.io/v1alpha1
        kind: Group
        metadata: { name: ${schema.spec.appName} }
        spec:
          forProvider: { name: ${schema.spec.appName}, type: external }
          providerConfigRef: { name: ${schema.spec.vaultProviderConfig} }

    - id: alias
      template:
        apiVersion: identity.vault.upbound.io/v1alpha1
        kind: GroupAlias
        metadata: { name: ${schema.spec.appName} }
        spec:
          forProvider:
            name: ${schema.spec.appName}
            canonicalIdRef: { name: ${grp.metadata.name} }
            mountAccessor: ${schema.spec.mountAccessor}
          providerConfigRef: { name: ${schema.spec.vaultProviderConfig} }
---
apiVersion: kro.run/v1alpha1
kind: Repro
metadata:
  name: demo
  namespace: default
spec:
  appName: hello-backend
  vaultProviderConfig: vault-provider-config
  mountAccessor: <>

Diagnostics you might ask me to run

To rule out CRD/version discovery problems or naming mismatches:

kubectl get crd groupaliases.identity.vault.upbound.io -o yaml \ 
  | yq '.spec.scope, [.spec.versions[].name]'

"Cluster"
[
  "v1alpha1"
]
  • and my RGD is Active
 appaccess  v1alpha1   AppAccess  Active  ["argocdAdminRole","argocdAdminBinding","argocdExecRole","argocdExecBinding","argocdViewRole","argocdViewBinding","kcAdmin","kcExec","kcView","kcVault","pushInitData","vaultPolicy","vaultGroup","vaultPolicy"
Name:         hello-backend-access
Namespace:    default
Labels:       argocd.argoproj.io/instance=kro
              kro.run/kro-version=v0.4.1
              kro.run/owned=true
              kro.run/resource-graph-definition-name=appaccess
API Version:  kro.run/v1alpha1
Kind:         AppAccess
Spec:
  App Name:                       hello-backend
  Argo Client Ref Name:           argo-cd-client
  Argo Namespace:                 argocd-system
  Enable Exec:                    true
  Enable Keycloak:                true
  Enable Keycloak Vault Roles:    true
  Enable Vault:                   true
  Enable View:                    true
  Keycloak Provider Config:       keycloak-provider-config
  Push Secret API Version:        external-secrets.io/v1alpha1
  Realm:                          master-realm
  Vault Client Ref Name:          vault-client
  Vault Kv Mount:                 secrets
  Vault Mount Accessor:           <auth>
  Vault Placeholder Secret Name:  vault-placeholder-secret
  Vault Provider Config:          vault-provider-config
  Vault Secret Store:             vault-backend
Status:
  Conditions:
    Message:               failed to create resource: the server could not find the requested resource
    Observed Generation:   1
    Reason:                ReconciliationFailed
    Status:                False
    Type:                  InstanceSynced
  State:                   ERROR
Events:                    <none>

Manually applying (works)

apiVersion: identity.vault.upbound.io/v1alpha1
kind: GroupAlias
metadata:
  name: hello-backend
  namespace: default
spec:
  forProvider:
    name: hello-backend
    canonicalIdRef:
      name: hello-backend     # references the Vault Group managed resource
    mountAccessor: <mountAccessor>
  providerConfigRef:
    name: <vault-provider-config>
---
apiVersion: identity.vault.upbound.io/v1alpha1
kind: GroupAlias
metadata:
  name: hello-backend
  namespace: default
spec:
  forProvider:
    name: hello-backend
    canonicalId: "<REPLACE_WITH_VAULT_GROUP_CANONICAL_ID>"
    mountAccessor:<auth>
  providerConfigRef:
    name: vault-provider-config
  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Which option describes the most your issue?

Instance (Create, Update, Deletion)

Metadata

Metadata

Labels

kind/bugCategorizes issue or PR as related to a bug.needs-triageIndicates an issue or PR lacks a `triage/foo` label and requires one.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions