writes: CREATE envoie toujours vers l'URL de collection {path}, incompatible avec les APIs où la clé est dans l'URL (ex: HashiCorp Vault) #1

Open
opened 2026-06-18 15:41:24 +02:00 by xmortelette · 0 comments

Contexte

En tentant d'utiliser kuberest pour configurer HashiCorp Vault 1.17.3 via son API REST, nous avons rencontré une incompatibilité fondamentale avec le mécanisme writes.

Comportement actuel

Avec une configuration de type :

writes:
- name: oidc_role_reader
  path: auth/oidc/role
  items:
  - name: reader
    values: |
      user_claim: email
      policies: ["allow_view_all"]

kuberest envoie la requête de création vers l'URL de collection :

POST /v1/auth/oidc/role
Body: { id: "reader", user_claim: "email", ... }

Résultat : 405 Method Not Allowed — vault répond unsupported operation.

Nous avons également testé createMethod: Put : le verbe change (PUT) mais kuberest envoie toujours vers {path} (URL de collection), pas vers {path}/{name} (URL d'instance).

PUT /v1/auth/oidc/role   → 405 unsupported operation

Comportement attendu par l'API Vault

L'API HashiCorp Vault suit un pattern REST où la clé est dans l'URL même pour la création :

Opération URL Body
Create/Update POST /v1/auth/oidc/role/reader {user_claim: "email", ...}
Read GET /v1/auth/oidc/role/reader
Delete DELETE /v1/auth/oidc/role/reader
List GET /v1/auth/oidc/role?list=true

C'est le pattern "PUT-centric" : POST {collection}/{id} pour créer ET mettre à jour. La même API est utilisée pour d'autres ressources :

  • POST /v1/auth/kubernetes/role/{name}
  • POST /v1/sys/policies/acl/{name}
  • POST /v1/auth/oidc/config (singleton)

Ce qui fonctionne en contournement

Le script post (Rhai) avec client.post() direct :

client.post("auth/oidc/role/reader", #{
  user_claim: "email",
  policies: ["allow_view_all"],
  ttl: "1h"
});

Logs confirmant que ça fonctionne :

http_post 'https://vault.demo-system:8200/v1/auth/oidc/role/reader'  → 204 No Content ✓
http_post 'https://vault.demo-system:8200/v1/auth/kubernetes/role/default' → 204 ✓

Mais ce contournement perd le mécanisme de réconciliation déclarative de kuberest.

Demande d'évolution

Serait-il possible d'ajouter une option sur le write group permettant que le CREATE utilise l'URL d'instance {path}/{name} plutôt que l'URL de collection {path} ?

Par exemple un champ createWithKeyInPath: true (nom à définir) :

writes:
- name: oidc_role_reader
  path: auth/oidc/role
  createWithKeyInPath: true   # ← CREATE → POST {path}/{name}, pas POST {path}
  items:
  - name: reader
    values: |
      user_claim: email

Ce qui produirait :

POST /v1/auth/oidc/role/reader   ← clé dans l'URL ✓
Body: { user_claim: "email", ... }

Versions testées :

  • kuberest : v0.7.x (sur cluster nightwing)
  • HashiCorp Vault : 1.17.3 LTS
  • bank-vaults operator : v1.31.4
## Contexte En tentant d'utiliser kuberest pour configurer HashiCorp Vault 1.17.3 via son API REST, nous avons rencontré une incompatibilité fondamentale avec le mécanisme `writes`. ## Comportement actuel Avec une configuration de type : ```yaml writes: - name: oidc_role_reader path: auth/oidc/role items: - name: reader values: | user_claim: email policies: ["allow_view_all"] ``` kuberest envoie la requête de création vers **l'URL de collection** : ``` POST /v1/auth/oidc/role Body: { id: "reader", user_claim: "email", ... } ``` Résultat : `405 Method Not Allowed` — vault répond `unsupported operation`. Nous avons également testé `createMethod: Put` : le verbe change (PUT) mais kuberest envoie **toujours vers `{path}`** (URL de collection), pas vers `{path}/{name}` (URL d'instance). ``` PUT /v1/auth/oidc/role → 405 unsupported operation ``` ## Comportement attendu par l'API Vault L'API HashiCorp Vault suit un pattern REST où **la clé est dans l'URL même pour la création** : | Opération | URL | Body | |-----------|-----|------| | Create/Update | `POST /v1/auth/oidc/role/reader` | `{user_claim: "email", ...}` | | Read | `GET /v1/auth/oidc/role/reader` | — | | Delete | `DELETE /v1/auth/oidc/role/reader` | — | | List | `GET /v1/auth/oidc/role?list=true` | — | C'est le pattern "PUT-centric" : `POST {collection}/{id}` pour créer ET mettre à jour. La même API est utilisée pour d'autres ressources : - `POST /v1/auth/kubernetes/role/{name}` - `POST /v1/sys/policies/acl/{name}` - `POST /v1/auth/oidc/config` (singleton) ## Ce qui fonctionne en contournement Le script `post` (Rhai) avec `client.post()` direct : ```rhai client.post("auth/oidc/role/reader", #{ user_claim: "email", policies: ["allow_view_all"], ttl: "1h" }); ``` Logs confirmant que ça fonctionne : ``` http_post 'https://vault.demo-system:8200/v1/auth/oidc/role/reader' → 204 No Content ✓ http_post 'https://vault.demo-system:8200/v1/auth/kubernetes/role/default' → 204 ✓ ``` Mais ce contournement perd le mécanisme de réconciliation déclarative de kuberest. ## Demande d'évolution Serait-il possible d'ajouter une option sur le write group permettant que le CREATE utilise l'URL d'instance `{path}/{name}` plutôt que l'URL de collection `{path}` ? Par exemple un champ `createWithKeyInPath: true` (nom à définir) : ```yaml writes: - name: oidc_role_reader path: auth/oidc/role createWithKeyInPath: true # ← CREATE → POST {path}/{name}, pas POST {path} items: - name: reader values: | user_claim: email ``` Ce qui produirait : ``` POST /v1/auth/oidc/role/reader ← clé dans l'URL ✓ Body: { user_claim: "email", ... } ``` Versions testées : - kuberest : v0.7.x (sur cluster nightwing) - HashiCorp Vault : 1.17.3 LTS - bank-vaults operator : v1.31.4
Sign in to join this conversation.