Skip to content

CLI ci fetch and ci run fail on every real secret envelope #793

Description

@rubenvdlinde

keepiq ci fetch and keepiq ci run cannot decrypt a secret from a real Keepiq server. The CLI expects a different envelope shape than the server sends, so every fetch stops with unexpected envelope scheme "".

Where, at development b5727e0:

  • cli/internal/client/client.go:201-207 MachineEnvelope reads a top-level scheme and payload.value.
  • cli/ci.go:65-68 fetchDecrypt() refuses any scheme other than rsa-oaep-sha256-chunked-v1, then decrypts env.Payload.Value.
  • lib/Service/MachineSecretEnvelopeService.php:129-153 serialize() puts the scheme under encryption.scheme and the ciphertext under ciphertext.key, ciphertext.login and ciphertext.additionalFields. There is no top-level scheme and no payload.
  • lib/Service/MachineSecretResponseService.php:116 answers the by-name route with exactly that serialize() output.
  • cli/internal/client/client_test.go:28 fakes the server with the CLI's own shape, so the Go test passes.

type MachineEnvelope struct {
Format string `json:"format"`
Scheme string `json:"scheme"`
Payload struct {
Value string `json:"value"`
} `json:"payload"`
}

keepiq/cli/ci.go

Lines 59 to 69 in b5727e0

// with the application private key (§4.2). Returns the plaintext value.
func fetchDecrypt(c *client.Client, key *rsa.PrivateKey, name, bearer string) (string, error) {
env, err := c.FetchByName(name, bearer)
if err != nil {
return "", err
}
if env.Scheme != "rsa-oaep-sha256-chunked-v1" {
return "", fmt.Errorf("unexpected envelope scheme %q", env.Scheme)
}
return dcrypto.DecryptField(env.Payload.Value, key)
}

public function serialize(Secret $secret): array {
return [
'format' => self::FORMAT,
'secret' => [
'id' => $secret->getId(),
'name' => $secret->getName(),
'url' => $secret->getUrl(),
'folderPath' => $this->resolveFolderPath(folderId: $secret->getFolderId()),
'type' => $secret->getTypeId(),
'createdAt' => $secret->getCreatedAt()?->format('c'),
'updatedAt' => $secret->getUpdatedAt()?->format('c'),
'keyUpdatedAt' => $secret->getKeyUpdatedAt()?->format('c'),
],
'encryption' => [
'suiteId' => $secret->getEncryptionSuiteId(),
'certificateFingerprint' => $this->certificateFingerprint(suiteId: $secret->getEncryptionSuiteId()),
'scheme' => self::SCHEME,
],
'ciphertext' => [
'key' => $secret->getKey(),
'login' => $secret->getLogin(),
'additionalFields' => $secret->getAdditionalFields(),
],
];
}//end serialize()

Go leaves Scheme empty when the JSON has no top-level scheme. The check at ci.go:65 then fails before any decryption. ci run uses the same fetchDecrypt(), so no secret reaches the child process. The lease line at ci.go:84-86 is never printed either.

Specified fix: openspec/changes/apps-client-libraries-and-ci, task 1.2 (tracking issue #776).

Found by the OpenSpec pass on 27 Sep 2026 and re-read at b5727e0 on 28 Sep.

Live check: register an application, grant it one secret, and run keepiq ci fetch <name> against the dev instance; an unexpected envelope scheme "" error confirms it.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingtriageAwaiting triage

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions