I run a freedesktop secrets service integration via keepassxc on linux and doppler login hangs when attempting to store the cli token using this service. I have to disable this service to get doppler login
to work. I use this keyring service for many other dev tools, so I’m surprised it doesn’t work with doppler. I’m running keepassxc version 2.7.9 and doppler version 3.70.0.
Hi @topocount !
Welcome to the Doppler Community!
The CLI is an open source project, so I went ahead and opened a GitHub issue for it here:
opened 04:30PM - 06 Jan 25 UTC
bug
**Describe the bug**
[Reported](https://community.doppler.com/t/trouble-with-th… e-keepassxc-secrets-service-integration/1730) in the community forum:
> I run a freedesktop secrets service integration via keepassxc on linux and doppler login hangs when attempting to store the cli token using this service. I have to disable this service to get doppler login to work. I use this keyring service for many other dev tools, so I’m surprised it doesn’t work with doppler. I’m running keepassxc version 2.7.9 and doppler version 3.70.0.
**Additional context**
* Issue reported/discussed in https://github.com/zalando/go-keyring/issues/88
* Apparently solved when using KeePassXC v2.7.9 or higher and go-keyring v0.2.4 or higher (we're on v0.2.1)
We use the go-keyring library and the issue you encountered seems to be described here:
opened 09:27PM - 16 Apr 23 UTC
Heya :wave:
I was checking out gh (the github cli) and it got stuck after run… ning `gh auth login`. So I dug a little and localized the issue in the interaction between this library and keepassxc, which I use as a keyring.
As far as I can tell, both this library and keepassxc are weird with the secret service protocol, so I'll cross-post it to their issue tracker.
While playring around, I've encountered unhandled errors and freeze.
Not sure about the freezes, but [the secret service api spec](https://specifications.freedesktop.org/secret-service/latest/ch08.html) this regarding IsLocked:
> A client application should always be ready to unlock the items for the secrets it needs, or objects it must modify. It must not assume that an item is already unlocked for whatever reason.
> A service may lock previously unlocked items for any reason at any time. Usually this is done in response to user actions, timeouts, or external actions (such as the computer sleeping). The inherent race conditions present due to this are unavoidable, and must be handled gracefully.
`gh auth login` freezes instead of exiting, but it does get a new token from github and saves it. It doesn't seem to apply, but as far as I can tell, that's because it fails to read the secret from the store. (Which arguably should be reported to the user, but it should also work.)
<details>
<summary>dbus-monitor, with messages not containing org.freedesktop.Secret removed</summary>
```
# 1.241 is gh
method call time=1681678963.125907 sender=:1.241 -> destination=org.freedesktop.secrets serial=2 path=/org/freedesktop/secrets; interface=org.freedesktop.DBus.Properties; member=Get
string "org.freedesktop.Secret.Service"
string "Collections"
method return time=1681678963.130388 sender=:1.28 -> destination=:1.241 serial=1575 reply_serial=2
variant array [
object path "/org/freedesktop/secrets/collection/passwords"
]
method call time=1681678963.130985 sender=:1.241 -> destination=org.freedesktop.secrets serial=3 path=/org/freedesktop/secrets; interface=org.freedesktop.Secret.Service; member=Unlock
array [
object path "/org/freedesktop/secrets/aliases/default"
]
method return time=1681678963.131601 sender=:1.28 -> destination=:1.241 serial=1576 reply_serial=3
array [
object path "/org/freedesktop/secrets/collection/passwords"
]
object path "/"
method call time=1681678963.132177 sender=:1.241 -> destination=org.freedesktop.secrets serial=4 path=/org/freedesktop/secrets/aliases/default; interface=org.freedesktop.Secret.Collection; member=SearchItems
array [
dict entry(
string "username"
string ""
)
dict entry(
string "service"
string "gh:github.com"
)
]
method return time=1681678963.133262 sender=:1.28 -> destination=:1.241 serial=1577 reply_serial=4
array [
object path "/org/freedesktop/secrets/collection/passwords/d72fb5ce71ea4196835b86ff53826c9b"
]
method call time=1681678963.133718 sender=:1.241 -> destination=org.freedesktop.secrets serial=5 path=/org/freedesktop/secrets; interface=org.freedesktop.Secret.Service; member=OpenSession
string "plain"
variant string ""
method return time=1681678963.134195 sender=:1.28 -> destination=:1.241 serial=1578 reply_serial=5
variant string ""
object path "/org/freedesktop/secrets/session/f4c480f8b9e64673ae53238eee74a4d6"
method call time=1681678963.134689 sender=:1.241 -> destination=org.freedesktop.secrets serial=6 path=/org/freedesktop/secrets/collection/passwords/d72fb5ce71ea4196835b86ff53826c9b; interface=org.freedesktop.Secret.Item; member=GetSecret
object path "/org/freedesktop/secrets/session/f4c480f8b9e64673ae53238eee74a4d6"
error time=1681678963.135092 sender=:1.28 -> destination=:1.241 error_name=org.freedesktop.Secret.Error.IsLocked reply_serial=6
method call time=1681678963.135611 sender=:1.241 -> destination=org.freedesktop.secrets serial=7 path=/org/freedesktop/secrets/session/f4c480f8b9e64673ae53238eee74a4d6; interface=org.freedesktop.Secret.Session; member=Close
method return time=1681678963.136162 sender=:1.28 -> destination=:1.241 serial=1580 reply_serial=7
method call time=1681678963.136718 sender=:1.241 -> destination=org.freedesktop.secrets serial=8 path=/org/freedesktop/secrets; interface=org.freedesktop.DBus.Properties; member=Get
string "org.freedesktop.Secret.Service"
string "Collections"
method return time=1681678963.137231 sender=:1.28 -> destination=:1.241 serial=1581 reply_serial=8
variant array [
object path "/org/freedesktop/secrets/collection/passwords"
]
method call time=1681678963.137773 sender=:1.241 -> destination=org.freedesktop.secrets serial=9 path=/org/freedesktop/secrets; interface=org.freedesktop.Secret.Service; member=Unlock
array [
object path "/org/freedesktop/secrets/aliases/default"
]
method return time=1681678963.138249 sender=:1.28 -> destination=:1.241 serial=1582 reply_serial=9
array [
object path "/org/freedesktop/secrets/collection/passwords"
]
object path "/"
method call time=1681678963.138731 sender=:1.241 -> destination=org.freedesktop.secrets serial=10 path=/org/freedesktop/secrets/aliases/default; interface=org.freedesktop.Secret.Collection; member=SearchItems
array [
dict entry(
string "service"
string "gh:github.com"
)
dict entry(
string "username"
string ""
)
]
method return time=1681678963.139639 sender=:1.28 -> destination=:1.241 serial=1583 reply_serial=10
array [
object path "/org/freedesktop/secrets/collection/passwords/d72fb5ce71ea4196835b86ff53826c9b"
]
method call time=1681678963.140248 sender=:1.241 -> destination=org.freedesktop.secrets serial=11 path=/org/freedesktop/secrets; interface=org.freedesktop.Secret.Service; member=OpenSession
string "plain"
variant string ""
method return time=1681678963.140984 sender=:1.28 -> destination=:1.241 serial=1584 reply_serial=11
variant string ""
object path "/org/freedesktop/secrets/session/3754810ae21f448091efecb69caf0fa5"
method call time=1681678963.141441 sender=:1.241 -> destination=org.freedesktop.secrets serial=12 path=/org/freedesktop/secrets/collection/passwords/d72fb5ce71ea4196835b86ff53826c9b; interface=org.freedesktop.Secret.Item; member=GetSecret
object path "/org/freedesktop/secrets/session/3754810ae21f448091efecb69caf0fa5"
error time=1681678963.142054 sender=:1.28 -> destination=:1.241 error_name=org.freedesktop.Secret.Error.IsLocked reply_serial=12
method call time=1681678963.142504 sender=:1.241 -> destination=org.freedesktop.secrets serial=13 path=/org/freedesktop/secrets/session/3754810ae21f448091efecb69caf0fa5; interface=org.freedesktop.Secret.Session; member=Close
method return time=1681678963.142976 sender=:1.28 -> destination=:1.241 serial=1586 reply_serial=13
```
</details>
### Tests
Here's my test tool:
```go
package main
import (
"fmt"
"os"
"github.com/zalando/go-keyring"
)
func main() {
var err error;
switch os.Args[1] {
case "set":
err = keyring.Set("gh:github.com", "foo", "aloha!")
case "get":
var secret string;
secret, err = keyring.Get("gh:github.com", "foo")
if err == nil {
fmt.Println(secret)
}
}
if err != nil {
fmt.Printf("err, %s\n", err)
}
}
```
These have a single password file opened and unlocked
Actual test cases have to go in comments because of github length restrictions :panda_face:
### Versions and stuff
Go stuff:
```
> cat go.mod
module test
go 1.20
require (
github.com/alessio/shellescape v1.4.1 // indirect
github.com/danieljoos/wincred v1.1.2 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/zalando/go-keyring v0.2.2 // indirect
golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c // indirect
)
```
Keepassxc debug output:
```
KeePassXC - Version 2.7.4
Qt 5.15.8
Debugging mode is disabled.
Operating system: Arch Linux
CPU architecture: x86_64
Kernel: linux 6.2.8-arch1-1
Enabled extensions:
- Auto-Type
- Browser Integration
- SSH Agent
- KeeShare
- YubiKey
- Secret Service Integration
Cryptographic libraries:
- Botan 2.19.3
```
dbus-daemon is `1.14.6`, just in case.
Generally, I'm on arch linux with a lot of stuff, including keepassxc, gh and go, pulled in via nix and home-manager
Apparently, this is resolved when using KeePassXC v2.7.9+ and go-keyring v0.2.4+. We’re currently on v0.2.1 of go-keyring, so we’ll see if bumping that depency helps! Updates will be posted to the GitHub issue.
Regards,
-Joel
1 Like
@topocount Could you try upgrading to Doppler CLI v3.71.1 and see if that solves the issue for you?
watsonian:
v3.71.1
Thanks this is working now. I had to do some finagling to get the CLI to utilize the keyring token instead of the one I saved to the config file but this is working as expected now.
I really appreciate the quick response