oidc-agent
oidc-agent copied to clipboard
oidc-agent-service does not persist on Mac
I'm not sure if this is the intended behavior or not, but oidc-agent
(when launched with eval
oidc-agent-service use``) does not persist when the shell session is restarted on Mac.
I haven't fully dug into the oidc-agent-service
script but I am guessing because it simply sets an env var OIDC_SOCK
that it will never persist between shell sessions.
Are there any plans to add support for persisting the agent between shell sessions? Unfortunately for Mac I think it would require integrating with launchd to ensure the process is tied to the user's login session instead of just the terminal session.
Also semi-related, sometimes when restarting oidc-agent
in a new shell session, accounts are unloaded and need to be manually re-added. Unclear if that is a bug or feature, but I expected accounts to stay loaded even across agent restarts.
For simple starts without any integration (see below), this behavior is expected.
As you already guessed, starting the agent with eval
sets the environment variable OIDC_SOCK
. This is also basically the same for oidc-agent
and oidc-agent-service
. The main difference here is, that oidc-agent
uses a socket with a random name. oidc-agent-service
will link this random socket to a well defined location, making integration a lot easier.
When you start the agent the env var is only set in that terminal, it won't be set in other already open terminals. But you can set the OIDC_SOCK
env var also there.
Also note, that if you close that terminal, the agent should still be running, however you need the value of OIDC_SOCK
to reach it.
For the integration/persistence: On linux we have integration with Xsession, this way the agent is automatically started at the beginning and available throughout the whole session. But this won't work on MacOS.
The easiest way to achieve persistence / integration throughout terminals is to use oidc-agent-service
(as you already do).
Starting the agent with eval `oidc-agent-service use`
still sets the environment variable only in that shell. However, OIDC_SOCK
will be set to well defined value, that doesn't change. It is /tmp/oidc-agent-service/$UID/oidc-agent.sock
.
Including something like export OIDC_SOCK=/tmp/oidc-agent-service/1000/oidc-agent.sock
in your .bashrc
(or similar file) should do the trick.
Now the env var should be available in all terminals you open. Also the agent can be restarted (using oidc-agent-service
without loosing this integration).
On your last point: It is expected that after a restart all loaded accounts are unloaded. The agent is always started with no accounts loaded.
(Note, that we have an auto-load feature so you don't have to load the accounts manually with oidc-add
, instead if you use oidc-token
with an account configuration that is not already loaded, the agent will prompt you for the encryption password and load the account before returning the access token. However, this requires our prompting utility oidc-prompt
which on mac depends on pashua
which can be installed with brew cask install pashua
, but it is likely that you already did and knew this.
It is /tmp/oidc-agent-service/$UID/oidc-agent.sock. Including something like export OIDC_SOCK=/tmp/oidc-agent-service/1000/oidc-agent.sock in your .bashrc (or similar file) should do the trick.
I see, for some reason it was stored under /tmp/oidc-agent-service/502/oidc-agent.sock
for me (I did start with oidc-agent-service in a previous session). I did confirm that setting the OIDC_SOCK
env var to this location worked.
Perhaps a followup question would be: is there any appetite for adapting oidc-agent-service
to run as a native launch daemon/agent under MacOS? I think there would be minimal (if any) code changes, and it would greatly improve the user experience on Mac. I believe it would also make logging much easier, which is a TODO item for Mac currently. If this seems like it would be worthwhile, I can at least do an initial investigation/proof of concept.
However, this requires our prompting utility oidc-prompt which on mac depends on pashua
I was a bit confused by this, because there are some features (such as oidc-add --print
) which also require the encryption password, but do so in the terminal and do not require pashua. Is there any reason why providing the encryption password for auto-loading an account can't also just be provided in the terminal?
Perhaps a followup question would be: is there any appetite for adapting
oidc-agent-service
to run as a native launch daemon/agent under MacOS? I think there would be minimal (if any) code changes, and it would greatly improve the user experience on Mac. I believe it would also make logging much easier, which is a TODO item for Mac currently. If this seems like it would be worthwhile, I can at least do an initial investigation/proof of concept.
I'm not familiar with how these things work on MacOS, so you should know this better. On Linux we are integrated with Xsession
which calls oidc-agent-service use
(with some checks) at the beginning of the session. A similar approach is absolutely appreciated also for MacOS. I would prefer a way with no changes to the existing code. However, it would not be a problem to add an additional command to oidc-agent-service
, e.g. start-mac-service
similar to start-from-x
.
If it would be necessary we also can do changes to oidc-agent
itself.
So feel free, to investigate and try this out. It is much appreciated. I'm no Mac user so it's a bit difficult for me to develop and test Mac features, but we are very happy to see oidc-agent
also being used on Mac.
However, this requires our prompting utility oidc-prompt which on mac depends on pashua
I was a bit confused by this, because there are some features (such as
oidc-add --print
) which also require the encryption password, but do so in the terminal and do not require pashua. Is there any reason why providing the encryption password for auto-loading an account can't also just be provided in the terminal?
Yes there is a simple (technical) reason (well, actually there are two sides on that issue, the other side is privacy/security):
- Privacy/Security: In the
oidc-agent
contextoidc-gen
andoidc-add
are "trusted" application, it is ok, if the user gives them the encryption password, they decrypt the account config, and sent it to the agent.oidc-token
on the other hand is just an application that wants to receive access tokens from the agent. In this way it is not different from other applications that want to do the same (we provide libraries for different languages, so that other applications can easily integrate with the agent). So when an application requests an AT for an account that is not loaded, we want to automatically load it, but therefore need the encryption password from the user. This password (and the decrypted config) should not be given to that applications (agent clients), so the agent has to ask the user itself. - Technical: And now comes the technical reason: While
oidc-add
/oidc-gen
are called by the user from a terminal,oidc-agent
runs as a daemon in the background and has no terminal attached. So it is just thatoidc-add
/oidc-gen
can do the prompting easily on the terminal, while the agent just cannot do terminal prompting.
As a more general piece of information: We currently have one person working on the windows integration. This will add some minimal GUI. I'm not sure how portable this is going to be, but I could imagine, that the ideas could be taken a step further in porting this to MacOs.
@zachmann
Technical: And now comes the technical reason: While oidc-add/oidc-gen are called by the user from a terminal, oidc-agent runs as a daemon in the background and has no terminal attached. So it is just that oidc-add/oidc-gen can do the prompting easily on the terminal, while the agent just cannot do terminal prompting.
Ahh I see, that makes sense. Unfortunately that may make running oidc-agent
under launchd a bit difficult because (from what I have read) Mac does not allow launchd-managed services to have any sort of GUI/prompts, but I would need to dig into it further.
@marcvs
As a more general piece of information: We currently have one person working on the windows integration. This will add some minimal GUI. I'm not sure how portable this is going to be, but I could imagine, that the ideas could be taken a step further in porting this to MacOs.
Thanks that is good to know- would definitely be interested in seeing some improvements there ported to Mac.
@zachmann revisiting this after a bit- It sounds like natively integrating with launchd will be a pretty big lift, at least more than I have time to commit to right now.
I think a reasonable workaround would be just instructing users to add a line such as eval "$(oidc-agent-service use)"
to their bashrc/zshrc file, which will effectively load or start the agent service at the beginning of any new session. This seems to work except the use
command always prints the PID to the terminal, which is not desirable. Would it be possible to either edit the use
command or add a new subcommand/flag to oidc-agent-service
that silently starts the agent without printing anything to the terminal?
Just append >/dev/null
at the end, i.e. eval $(oidc-agent-service use) >/dev/null
should do the trick.
If it helps, I can shortly describe my favorite setup on Mac OS. I prefer to use the LaunchAgents
mechanism to startup
daemons during the login process.
Installation
I used Homebrew to install oidc-agent
as described in the documentation.
brew tap indigo-dc/oidc-agent
brew install oidc-agent
Setup a LaunchAgent
User defined LaunchAgents
are located in /Users/<username>/Library/LaunchAgents
. In that directory, I created a file called edu.kit.oidc-agent.plist
. You can choose a different name as you like. The file contains the following xml style content.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>KeepAlive</key>
<true/>
<key>EnvironmentVariables</key>
<dict>
<key>OIDC_SOCK</key>
<string>/Users/<username>/.cache/oidc-agent/oidc-agent.sock</string>
<key>PATH</key>
<string>/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/homebrew/bin</string>
</dict>
<key>Label</key>
<string>oidc-agent</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/oidc-agent</string>
<string>-a</string>
<string>/Users/<username>/.cache/oidc-agent/oidc-agent.sock</string>
<string>-d</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StandardErrorPath</key>
<string>/usr/local/var/log/oidc-agent.log</string>
</dict>
</plist>
you have to replace <username>
with the username on your system. Please, be aware that you can use only a limited set of environment variables here. $HOME
does not work for example. In addition, if you use a ARM-based Mac, you have to exchange every /usr/local
by /opt/homebrew
, since the base directory of Homebrew changed for ARM-based Macs. Potentially, it also a good idea to manual create the directory /Users/<username>/.cache/oidc-agent/
before loading the LaunchAgent
.
After creating the file, you can load it with
launchctl load -w edu.kit.oidc-agent.plist
Doing a simple ps aux | grep oidc
should show that an agent is running.
ps aux | grep oidc
<username> 88214 0,0 0,0 34186308 208 ?? S Mi02pm 0:00.03 /usr/local/bin/oidc-agent -a /Users/<username>/.cache/oidc-agent/oidc-agent.sock -d
Now the last step is to incude the following line in your .zshrc
:
export OIDC_SOCK=/Users/<username>/.cache/oidc-agent/oidc-agent.sock
and open a new shell or run source .zshrc
.
Now LaunchAgent
takes care that always an oidc-agent
is running and points to the right socket.
To complete the oidc-agent
setup follow the instructions in the documentation.
The instructions work at least on my Intel with MacOs Monterey Version 12.6.3, but I think they will work on other versions as well.
Hope that helps, Manuel