[Feedback] OpenID and multi-user #1707

Closed
opened 2026-02-28 19:51:39 -06:00 by GiteaMirror · 162 comments
Owner

Originally created by @matt-fidd on GitHub (Dec 23, 2024).

Thanks to @lelemm, OpenID and multi-user support was added to Actual in #3878 as an experimental feature. This issue is to track feedback/bugs/issues/requests related specifically to that feature.

Originally created by @matt-fidd on GitHub (Dec 23, 2024). Thanks to @lelemm, OpenID and multi-user support was added to Actual in #3878 as an experimental feature. This issue is to track feedback/bugs/issues/requests related specifically to that feature.
GiteaMirror added the feedbackexperimental feature labels 2026-02-28 19:51:39 -06:00
Author
Owner

@shaankhosla commented on GitHub (Dec 24, 2024):

Thanks @lelemm for this amazing feature!

I'm having some trouble setting this up with Authelia. I'm getting the following error after trying to sign in with OpenId:

status	"error"
reason	"openid-grant-failed"

When I look at the logs for Actual I see the following:

2024-12-24T02:24:06.997Z info: GET 200 /account/needs-bootstrap
2024-12-24T02:24:07.054Z info: GET 304 /account/needs-bootstrap
2024-12-24T02:24:07.107Z info: GET 304 /account/needs-bootstrap
2024-12-24T02:24:07.168Z info: GET 200 /admin/owner-created/
Logging in via openid
2024-12-24T02:24:08.554Z info: POST 200 /account/login
OpenID grant failed: RPError: iss missing from the response
    at Client.callback (/app/node_modules/openid-client/lib/client.js:436:13)
    at loginWithOpenIdFinalize (file:///app/src/accounts/openid.js:177:31)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async file:///app/src/app-openid.js:86:24 {
  params: {
    code: '<redacted>',
    state: '<redacted>'
  }
}

Anyone know what I might be doing wrong?

@shaankhosla commented on GitHub (Dec 24, 2024): Thanks @lelemm for this amazing feature! I'm having some trouble setting this up with Authelia. I'm getting the following error after trying to sign in with OpenId: ``` status "error" reason "openid-grant-failed" ``` When I look at the logs for Actual I see the following: ```2024-12-24T02:23:34.852Z info: POST 200 /account/login 2024-12-24T02:24:06.997Z info: GET 200 /account/needs-bootstrap 2024-12-24T02:24:07.054Z info: GET 304 /account/needs-bootstrap 2024-12-24T02:24:07.107Z info: GET 304 /account/needs-bootstrap 2024-12-24T02:24:07.168Z info: GET 200 /admin/owner-created/ Logging in via openid 2024-12-24T02:24:08.554Z info: POST 200 /account/login OpenID grant failed: RPError: iss missing from the response at Client.callback (/app/node_modules/openid-client/lib/client.js:436:13) at loginWithOpenIdFinalize (file:///app/src/accounts/openid.js:177:31) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async file:///app/src/app-openid.js:86:24 { params: { code: '<redacted>', state: '<redacted>' } } ``` Anyone know what I might be doing wrong?
Author
Owner

@lelemm commented on GitHub (Dec 24, 2024):

I'm not on the PC right now, but maybe authelia does not implement openid, but oauth2.

If that's the case, you have to setup it using the config.json on the server specifying the authMethod to oauth2 instead of openid
Check this PR for more details https://github.com/actualbudget/actual-server/pull/527/files

Thanks @lelemm for this amazing feature!

I'm having some trouble setting this up with Authelia. I'm getting the following error after trying to sign in with OpenId:

status	"error"
reason	"openid-grant-failed"

When I look at the logs for Actual I see the following:

2024-12-24T02:24:06.997Z info: GET 200 /account/needs-bootstrap
2024-12-24T02:24:07.054Z info: GET 304 /account/needs-bootstrap
2024-12-24T02:24:07.107Z info: GET 304 /account/needs-bootstrap
2024-12-24T02:24:07.168Z info: GET 200 /admin/owner-created/
Logging in via openid
2024-12-24T02:24:08.554Z info: POST 200 /account/login
OpenID grant failed: RPError: iss missing from the response
    at Client.callback (/app/node_modules/openid-client/lib/client.js:436:13)
    at loginWithOpenIdFinalize (file:///app/src/accounts/openid.js:177:31)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async file:///app/src/app-openid.js:86:24 {
  params: {
    code: '<redacted>',
    state: '<redacted>'
  }
}

Anyone know what I might be doing wrong?

@lelemm commented on GitHub (Dec 24, 2024): I'm not on the PC right now, but maybe authelia does not implement openid, but oauth2. If that's the case, you have to setup it using the config.json on the server specifying the authMethod to oauth2 instead of openid Check this PR for more details https://github.com/actualbudget/actual-server/pull/527/files > Thanks @lelemm for this amazing feature! > > I'm having some trouble setting this up with Authelia. I'm getting the following error after trying to sign in with OpenId: > > ``` > status "error" > reason "openid-grant-failed" > ``` > > When I look at the logs for Actual I see the following: > > ``` > 2024-12-24T02:24:06.997Z info: GET 200 /account/needs-bootstrap > 2024-12-24T02:24:07.054Z info: GET 304 /account/needs-bootstrap > 2024-12-24T02:24:07.107Z info: GET 304 /account/needs-bootstrap > 2024-12-24T02:24:07.168Z info: GET 200 /admin/owner-created/ > Logging in via openid > 2024-12-24T02:24:08.554Z info: POST 200 /account/login > OpenID grant failed: RPError: iss missing from the response > at Client.callback (/app/node_modules/openid-client/lib/client.js:436:13) > at loginWithOpenIdFinalize (file:///app/src/accounts/openid.js:177:31) > at process.processTicksAndRejections (node:internal/process/task_queues:95:5) > at async file:///app/src/app-openid.js:86:24 { > params: { > code: '<redacted>', > state: '<redacted>' > } > } > ``` > > Anyone know what I might be doing wrong?
Author
Owner

@shaankhosla commented on GitHub (Dec 24, 2024):

I'm not on the PC right now, but maybe authelia does not implement openid, but oauth2.

If that's the case, you have to setup it using the config.json on the server specifying the authMethod to oauth2 instead of openid Check this PR for more details https://github.com/actualbudget/actual-server/pull/527/files

Thanks @lelemm for this amazing feature!
I'm having some trouble setting this up with Authelia. I'm getting the following error after trying to sign in with OpenId:

status	"error"
reason	"openid-grant-failed"

When I look at the logs for Actual I see the following:

2024-12-24T02:24:06.997Z info: GET 200 /account/needs-bootstrap
2024-12-24T02:24:07.054Z info: GET 304 /account/needs-bootstrap
2024-12-24T02:24:07.107Z info: GET 304 /account/needs-bootstrap
2024-12-24T02:24:07.168Z info: GET 200 /admin/owner-created/
Logging in via openid
2024-12-24T02:24:08.554Z info: POST 200 /account/login
OpenID grant failed: RPError: iss missing from the response
    at Client.callback (/app/node_modules/openid-client/lib/client.js:436:13)
    at loginWithOpenIdFinalize (file:///app/src/accounts/openid.js:177:31)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async file:///app/src/app-openid.js:86:24 {
  params: {
    code: '<redacted>',
    state: '<redacted>'
  }
}

Anyone know what I might be doing wrong?

Thanks, I'll dig around! I think Authelia has OpenID based on this, but I'll try the config.json.

@shaankhosla commented on GitHub (Dec 24, 2024): > I'm not on the PC right now, but maybe authelia does not implement openid, but oauth2. > > If that's the case, you have to setup it using the config.json on the server specifying the authMethod to oauth2 instead of openid Check this PR for more details https://github.com/actualbudget/actual-server/pull/527/files > > > Thanks @lelemm for this amazing feature! > > I'm having some trouble setting this up with Authelia. I'm getting the following error after trying to sign in with OpenId: > > ``` > > status "error" > > reason "openid-grant-failed" > > ``` > > > > > > > > > > > > > > > > > > > > > > > > When I look at the logs for Actual I see the following: > > ``` > > 2024-12-24T02:24:06.997Z info: GET 200 /account/needs-bootstrap > > 2024-12-24T02:24:07.054Z info: GET 304 /account/needs-bootstrap > > 2024-12-24T02:24:07.107Z info: GET 304 /account/needs-bootstrap > > 2024-12-24T02:24:07.168Z info: GET 200 /admin/owner-created/ > > Logging in via openid > > 2024-12-24T02:24:08.554Z info: POST 200 /account/login > > OpenID grant failed: RPError: iss missing from the response > > at Client.callback (/app/node_modules/openid-client/lib/client.js:436:13) > > at loginWithOpenIdFinalize (file:///app/src/accounts/openid.js:177:31) > > at process.processTicksAndRejections (node:internal/process/task_queues:95:5) > > at async file:///app/src/app-openid.js:86:24 { > > params: { > > code: '<redacted>', > > state: '<redacted>' > > } > > } > > ``` > > > > > > > > > > > > > > > > > > > > > > > > Anyone know what I might be doing wrong? Thanks, I'll dig around! I think Authelia has OpenID based on [this](https://www.authelia.com/integration/openid-connect/introduction/#openid), but I'll try the config.json.
Author
Owner

@shaankhosla commented on GitHub (Dec 24, 2024):

I'm not on the PC right now, but maybe authelia does not implement openid, but oauth2.
If that's the case, you have to setup it using the config.json on the server specifying the authMethod to oauth2 instead of openid Check this PR for more details https://github.com/actualbudget/actual-server/pull/527/files

Thanks @lelemm for this amazing feature!
I'm having some trouble setting this up with Authelia. I'm getting the following error after trying to sign in with OpenId:

status	"error"
reason	"openid-grant-failed"

When I look at the logs for Actual I see the following:

2024-12-24T02:24:06.997Z info: GET 200 /account/needs-bootstrap
2024-12-24T02:24:07.054Z info: GET 304 /account/needs-bootstrap
2024-12-24T02:24:07.107Z info: GET 304 /account/needs-bootstrap
2024-12-24T02:24:07.168Z info: GET 200 /admin/owner-created/
Logging in via openid
2024-12-24T02:24:08.554Z info: POST 200 /account/login
OpenID grant failed: RPError: iss missing from the response
    at Client.callback (/app/node_modules/openid-client/lib/client.js:436:13)
    at loginWithOpenIdFinalize (file:///app/src/accounts/openid.js:177:31)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async file:///app/src/app-openid.js:86:24 {
  params: {
    code: '<redacted>',
    state: '<redacted>'
  }
}

Anyone know what I might be doing wrong?

Thanks, I'll dig around! I think Authelia has OpenID based on this, but I'll try the config.json.

I tried with the config.json and set the authMethod to "oauth2" but still got the same error.

@shaankhosla commented on GitHub (Dec 24, 2024): > > I'm not on the PC right now, but maybe authelia does not implement openid, but oauth2. > > If that's the case, you have to setup it using the config.json on the server specifying the authMethod to oauth2 instead of openid Check this PR for more details https://github.com/actualbudget/actual-server/pull/527/files > > > Thanks @lelemm for this amazing feature! > > > I'm having some trouble setting this up with Authelia. I'm getting the following error after trying to sign in with OpenId: > > > ``` > > > status "error" > > > reason "openid-grant-failed" > > > ``` > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > When I look at the logs for Actual I see the following: > > > ``` > > > 2024-12-24T02:24:06.997Z info: GET 200 /account/needs-bootstrap > > > 2024-12-24T02:24:07.054Z info: GET 304 /account/needs-bootstrap > > > 2024-12-24T02:24:07.107Z info: GET 304 /account/needs-bootstrap > > > 2024-12-24T02:24:07.168Z info: GET 200 /admin/owner-created/ > > > Logging in via openid > > > 2024-12-24T02:24:08.554Z info: POST 200 /account/login > > > OpenID grant failed: RPError: iss missing from the response > > > at Client.callback (/app/node_modules/openid-client/lib/client.js:436:13) > > > at loginWithOpenIdFinalize (file:///app/src/accounts/openid.js:177:31) > > > at process.processTicksAndRejections (node:internal/process/task_queues:95:5) > > > at async file:///app/src/app-openid.js:86:24 { > > > params: { > > > code: '<redacted>', > > > state: '<redacted>' > > > } > > > } > > > ``` > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Anyone know what I might be doing wrong? > > Thanks, I'll dig around! I think Authelia has OpenID based on [this](https://www.authelia.com/integration/openid-connect/introduction/#openid), but I'll try the config.json. I tried with the config.json and set the authMethod to "oauth2" but still got the same error.
Author
Owner

@lelemm commented on GitHub (Dec 24, 2024):

I'm not on the PC right now, but maybe authelia does not implement openid, but oauth2.
If that's the case, you have to setup it using the config.json on the server specifying the authMethod to oauth2 instead of openid Check this PR for more details https://github.com/actualbudget/actual-server/pull/527/files

Thanks @lelemm for this amazing feature!
I'm having some trouble setting this up with Authelia. I'm getting the following error after trying to sign in with OpenId:

status	"error"
reason	"openid-grant-failed"

When I look at the logs for Actual I see the following:

2024-12-24T02:24:06.997Z info: GET 200 /account/needs-bootstrap
2024-12-24T02:24:07.054Z info: GET 304 /account/needs-bootstrap
2024-12-24T02:24:07.107Z info: GET 304 /account/needs-bootstrap
2024-12-24T02:24:07.168Z info: GET 200 /admin/owner-created/
Logging in via openid
2024-12-24T02:24:08.554Z info: POST 200 /account/login
OpenID grant failed: RPError: iss missing from the response
    at Client.callback (/app/node_modules/openid-client/lib/client.js:436:13)
    at loginWithOpenIdFinalize (file:///app/src/accounts/openid.js:177:31)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async file:///app/src/app-openid.js:86:24 {
  params: {
    code: '<redacted>',
    state: '<redacted>'
  }
}

Anyone know what I might be doing wrong?

Thanks, I'll dig around! I think Authelia has OpenID based on this, but I'll try the config.json.

I tried with the config.json and set the authMethod to "oauth2" but still got the same error.

To use the configuration in the file, you need to run the commands.
First disable the openid
yarn/npm run disable-openid
Then run
yarn/npm run enable-openid

This script will take the configuration from the file into the database

@lelemm commented on GitHub (Dec 24, 2024): > > > I'm not on the PC right now, but maybe authelia does not implement openid, but oauth2. > > > If that's the case, you have to setup it using the config.json on the server specifying the authMethod to oauth2 instead of openid Check this PR for more details https://github.com/actualbudget/actual-server/pull/527/files > > > > Thanks @lelemm for this amazing feature! > > > > I'm having some trouble setting this up with Authelia. I'm getting the following error after trying to sign in with OpenId: > > > > ``` > > > > status "error" > > > > reason "openid-grant-failed" > > > > ``` > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > When I look at the logs for Actual I see the following: > > > > ``` > > > > 2024-12-24T02:24:06.997Z info: GET 200 /account/needs-bootstrap > > > > 2024-12-24T02:24:07.054Z info: GET 304 /account/needs-bootstrap > > > > 2024-12-24T02:24:07.107Z info: GET 304 /account/needs-bootstrap > > > > 2024-12-24T02:24:07.168Z info: GET 200 /admin/owner-created/ > > > > Logging in via openid > > > > 2024-12-24T02:24:08.554Z info: POST 200 /account/login > > > > OpenID grant failed: RPError: iss missing from the response > > > > at Client.callback (/app/node_modules/openid-client/lib/client.js:436:13) > > > > at loginWithOpenIdFinalize (file:///app/src/accounts/openid.js:177:31) > > > > at process.processTicksAndRejections (node:internal/process/task_queues:95:5) > > > > at async file:///app/src/app-openid.js:86:24 { > > > > params: { > > > > code: '<redacted>', > > > > state: '<redacted>' > > > > } > > > > } > > > > ``` > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Anyone know what I might be doing wrong? > > > > > > Thanks, I'll dig around! I think Authelia has OpenID based on [this](https://www.authelia.com/integration/openid-connect/introduction/#openid), but I'll try the config.json. > > I tried with the config.json and set the authMethod to "oauth2" but still got the same error. To use the configuration in the file, you need to run the commands. First disable the openid yarn/npm run disable-openid Then run yarn/npm run enable-openid This script will take the configuration from the file into the database
Author
Owner

@shaankhosla commented on GitHub (Dec 24, 2024):

Ah thanks, I didn't realize I had to run that command for it to use the config. That worked! I had to switch my docker container from edge-alpine to just edge to have npm in it.

@shaankhosla commented on GitHub (Dec 24, 2024): Ah thanks, I didn't realize I had to run that command for it to use the config. That worked! I had to switch my docker container from edge-alpine to just edge to have npm in it.
Author
Owner

@shaankhosla commented on GitHub (Dec 24, 2024):

Actually, that seemed like it fixed the issue but I don't think it did.

After I run those commands I'm able to sign in (with account A) and assign a budget file to myself as admin. However, if I try to sign in through a different user account (with account B) in incognito mode I get the same openid-grant-failed error I was seeing before. I then re-ran the disable/enable commands again and signed in with account B, at which point account B became the admin and I couldn't see account A in the user directory list. Then I tried signing in with account A and got the same openid-grant-failed error as before.

@shaankhosla commented on GitHub (Dec 24, 2024): Actually, that seemed like it fixed the issue but I don't think it did. After I run those commands I'm able to sign in (with account A) and assign a budget file to myself as admin. However, if I try to sign in through a different user account (with account B) in incognito mode I get the same `openid-grant-failed` error I was seeing before. I then re-ran the disable/enable commands again and signed in with account B, at which point account B became the admin and I couldn't see account A in the user directory list. Then I tried signing in with account A and got the same `openid-grant-failed` error as before.
Author
Owner

@lelemm commented on GitHub (Dec 24, 2024):

You have to give access to the second user in the user directory

@lelemm commented on GitHub (Dec 24, 2024): You have to give access to the second user in the user directory
Author
Owner

@lelemm commented on GitHub (Dec 24, 2024):

@shaankhosla https://deploy-preview-447.www.actualbudget.org/docs/experimental/multi-user

@lelemm commented on GitHub (Dec 24, 2024): @shaankhosla https://deploy-preview-447.www.actualbudget.org/docs/experimental/multi-user
Author
Owner

@shaankhosla commented on GitHub (Dec 24, 2024):

Got it, it's working as expected. I thought that new users would be added to that automatically at sign in. Thanks for all of your help!

@shaankhosla commented on GitHub (Dec 24, 2024): Got it, it's working as expected. I thought that new users would be added to that automatically at sign in. Thanks for all of your help!
Author
Owner

@feyleth commented on GitHub (Dec 29, 2024):

it is possible to use multi-user without need to login with openID ?

@feyleth commented on GitHub (Dec 29, 2024): it is possible to use multi-user without need to login with openID ?
Author
Owner

@lelemm commented on GitHub (Dec 29, 2024):

it is possible to use multi-user without need to login with openID ?

Nope. They are tied together for now. One can expand for internal user management

@lelemm commented on GitHub (Dec 29, 2024): > it is possible to use multi-user without need to login with openID ? Nope. They are tied together for now. One can expand for internal user management
Author
Owner

@alexsalex commented on GitHub (Jan 2, 2025):

HI! Thank you for this future! Amazing!

But could you write some documentation about it? For example: what is the redirect URL for OAuth2?

@alexsalex commented on GitHub (Jan 2, 2025): HI! Thank you for this future! Amazing! But could you write some documentation about it? For example: **what is the redirect URL for OAuth2?**
Author
Owner
@lelemm commented on GitHub (Jan 2, 2025): https://your-actual-server-domain:your-actual-server/openid/callback
Author
Owner

@nichtdu commented on GitHub (Jan 7, 2025):

just added via authentik. worked flawless so far. Enabling was quiet easy as well.

The fact that it deletes the url in case you change auth-provider in setup is a little confusing though - or rather the fact that it accepts invalid url and does not tell you (it resetted to placeholders but i did not notice and hit ok again - and i was not able to see error on first sight)

@nichtdu commented on GitHub (Jan 7, 2025): just added via authentik. worked flawless so far. Enabling was quiet easy as well. The fact that it deletes the url in case you change auth-provider in setup is a little confusing though - or rather the fact that it accepts invalid url and does not tell you (it resetted to placeholders but i did not notice and hit ok again - and i was not able to see error on first sight)
Author
Owner

@mocdaniel commented on GitHub (Jan 7, 2025):

I noticed that arbitrary users seem to be able to access budget files of other users as long as they log in from the same device.

Consider the following situation - I got two users in my IAM solution (Authentik), one is called Daniel Bodky and is Admin in Actualbudget, the other is called John Doe and got added to the user directory of Actualbudget manually:

Screenshot 2025-01-07 at 12 26 24

There is only one budget file available on the server, called Daniel. It has been created by the admin user and is configured to be accessible only by him:

Screenshot 2025-01-07 at 12 26 32

However, if I log in to Actualbudget with the second user John Doe, I am offered to open the budget file. It even states that the supposedly unprivileged user is the file owner. Consequently, I can open and edit the budget with the unprivileged user (note the username in the top right):

Screenshot 2025-01-07 at 12 24 23

Screenshot 2025-01-07 at 12 25 10

If I login as John Doe from a private browser window, the behavior is as expected: The user doesn't have a budget file yet, so none is displayed; the budget file(s) of other users don't show either.

Screenshot 2025-01-07 at 12 24 27

I guess this is due to the offline capabilities of Actualbudget, and the fact that all local files are available in the device/browser? So once a budget file has been downloaded to a device/browser, it's accessible to all users that might log in on that device/browser?

@mocdaniel commented on GitHub (Jan 7, 2025): I noticed that arbitrary users seem to be able to access budget files of other users as long as they log in from the same device. Consider the following situation - I got two users in my IAM solution (Authentik), one is called **Daniel Bodky** and is Admin in Actualbudget, the other is called **John Doe** and got added to the user directory of Actualbudget manually: ![Screenshot 2025-01-07 at 12 26 24](https://github.com/user-attachments/assets/c0e7f3f8-fc8e-4025-ad07-5e9d930e9bad) There is only one budget file available on the server, called **Daniel**. It has been created by the admin user and is configured to be accessible only by him: ![Screenshot 2025-01-07 at 12 26 32](https://github.com/user-attachments/assets/cfd0b8e7-2b05-452f-b692-78d73a6a8916) However, if I log in to Actualbudget with the second user **John Doe**, I am offered to open the budget file. It even states that the supposedly unprivileged user is the file owner. Consequently, I can open and edit the budget with the unprivileged user (note the username in the top right): ![Screenshot 2025-01-07 at 12 24 23](https://github.com/user-attachments/assets/e2a0d9eb-b960-49e2-b3ef-1a9f1226e885) ![Screenshot 2025-01-07 at 12 25 10](https://github.com/user-attachments/assets/9ab7f4f9-9b84-4551-a830-29406f68a777) If I login as **John Doe** from a private browser window, the behavior is as expected: The user doesn't have a budget file yet, so none is displayed; the budget file(s) of other users don't show either. ![Screenshot 2025-01-07 at 12 24 27](https://github.com/user-attachments/assets/b1b80047-2946-458a-afed-f638c55de2bc) I guess this is due to the offline capabilities of Actualbudget, and the fact that all _local_ files are available in the device/browser? So once a budget file has been downloaded to a device/browser, it's accessible to all users that might log in on that device/browser?
Author
Owner

@lelemm commented on GitHub (Jan 7, 2025):

I guess this is due to the offline capabilities of Actualbudget, and the fact that all local files are available in the device/browser? So once a budget file has been downloaded to a device/browser, it's accessible to all users that might log in on that device/browser?

You are completely right. That's how its working atm

@lelemm commented on GitHub (Jan 7, 2025): > I guess this is due to the offline capabilities of Actualbudget, and the fact that all _local_ files are available in the device/browser? So once a budget file has been downloaded to a device/browser, it's accessible to all users that might log in on that device/browser? You are completely right. That's how its working atm
Author
Owner

@mocdaniel commented on GitHub (Jan 7, 2025):

Are there plans to mitigate this behavior in the future? Maybe by 'disabling' offline mode when enabling OIDC auth/multi-user support?

@mocdaniel commented on GitHub (Jan 7, 2025): Are there plans to mitigate this behavior in the future? Maybe by 'disabling' offline mode when enabling OIDC auth/multi-user support?
Author
Owner

@lelemm commented on GitHub (Jan 7, 2025):

AFAIK, not planned, but I guess with enough feedback for it will probably be mitigated

@lelemm commented on GitHub (Jan 7, 2025): AFAIK, not planned, but I guess with enough feedback for it will probably be mitigated
Author
Owner

@ReclaimedBytes commented on GitHub (Jan 7, 2025):

Working well here with Pocket ID. Thanks for implementing!

@ReclaimedBytes commented on GitHub (Jan 7, 2025): Working well here with Pocket ID. Thanks for implementing!
Author
Owner

@lelemm commented on GitHub (Jan 7, 2025):

Would be nice if someone is using a different OpenID provider, give some information like this:

    {
      label: 'Microsoft Entra',
      value: 'microsoft',
      issuer: 'https://login.microsoftonline.com/{tenant-id}',
      clientIdRequired: true,
      clientSecretRequired: true,
      tip: (
        <Link
          variant="external"
          to="https://learn.microsoft.com/en-us/entra/identity-platform/v2-protocols-oidc"
        >
          <Trans>OpenID Connect on the Microsoft identity platform</Trans>
        </Link>
      ),
    }

So the list of validated providers can be increased for future users

@lelemm commented on GitHub (Jan 7, 2025): Would be nice if someone is using a different OpenID provider, give some information like this: ```jsx { label: 'Microsoft Entra', value: 'microsoft', issuer: 'https://login.microsoftonline.com/{tenant-id}', clientIdRequired: true, clientSecretRequired: true, tip: ( <Link variant="external" to="https://learn.microsoft.com/en-us/entra/identity-platform/v2-protocols-oidc" > <Trans>OpenID Connect on the Microsoft identity platform</Trans> </Link> ), } ``` So the list of validated providers can be increased for future users
Author
Owner

@ReclaimedBytes commented on GitHub (Jan 7, 2025):

Where would I find that?

@ReclaimedBytes commented on GitHub (Jan 7, 2025): Where would I find that?
Author
Owner

@lelemm commented on GitHub (Jan 7, 2025):

Where would I find that?

That would be built by you, if you have the knowledge

@lelemm commented on GitHub (Jan 7, 2025): > Where would I find that? That would be built by you, if you have the knowledge
Author
Owner

@woolfyx commented on GitHub (Jan 7, 2025):

Firstly, thanks for this great features ! 😍

Quick question regarding claims used to retrieve user information.Actually, at least for Entra ID, the username seems to be mapped to the display name? Is it correct? Maybe it can be interesting to be customized to use the UPN (which is unique in Entra ID - not sure it's the case for display name), for example?

This question aside, authentication process works perfectly.

@woolfyx commented on GitHub (Jan 7, 2025): Firstly, thanks for this great features ! 😍 Quick question regarding claims used to retrieve user information.Actually, at least for Entra ID, the username seems to be mapped to the display name? Is it correct? Maybe it can be interesting to be customized to use the UPN (which is unique in Entra ID - not sure it's the case for display name), for example? This question aside, authentication process works perfectly.
Author
Owner

@lelemm commented on GitHub (Jan 7, 2025):

Firstly, thanks for this great features ! 😍

Quick question regarding claims used to retrieve user information.Actually, at least for Entra ID, the username seems to be mapped to the display name? Is it correct? Maybe it can be interesting to be customized to use the UPN (which is unique in Entra ID - not sure it's the case for display name), for example?

This question aside, authentication process works perfectly.

The username saved is a little clunky honestly.
in the spec, there are definitions of the name of the fields, but I guess some providers just do what they want lol.
probably for Entra Id is catching a bad value (on the big list of possible values).

@lelemm commented on GitHub (Jan 7, 2025): > Firstly, thanks for this great features ! 😍 > > Quick question regarding claims used to retrieve user information.Actually, at least for Entra ID, the username seems to be mapped to the display name? Is it correct? Maybe it can be interesting to be customized to use the UPN (which is unique in Entra ID - not sure it's the case for display name), for example? > > This question aside, authentication process works perfectly. The username saved is a little clunky honestly. in the spec, there are definitions of the name of the fields, but I guess some providers just do what they want lol. probably for Entra Id is catching a bad value (on the big list of possible values).
Author
Owner

@Arnoud-B commented on GitHub (Jan 7, 2025):

To test this, I:

  1. Created an account on auth0, created a (fake) web app and created a user there. For the callback URL I used https://actual.domain.com:5006/openid/callback.
  2. Attempted a sign in with the user I created on auth0 and got an error message. I went back to the login page to try again, and now it logged me in automatically (weird?).
  3. I opened a budget file, which worked. But when closing the budget file, it says: "Owner: Unassigned". Another budget file is showing the same, and a third (test) budget file is showing "Owner: Server". I expected the Owner to be the first OpenID user to open the budget file.
@Arnoud-B commented on GitHub (Jan 7, 2025): To test this, I: 1. Created an account on auth0, created a (fake) web app and created a user there. For the callback URL I used https://actual.domain.com:5006/openid/callback. 2. Attempted a sign in with the user I created on auth0 and got an error message. I went back to the login page to try again, and now it logged me in automatically (weird?). 3. I opened a budget file, which worked. But when closing the budget file, it says: "Owner: Unassigned". Another budget file is showing the same, and a third (test) budget file is showing "Owner: Server". I expected the Owner to be the first OpenID user to open the budget file.
Author
Owner

@jsimcina commented on GitHub (Jan 7, 2025):

Am I missing something? When trying to set OpenID via env variables, do I need to set a config.json file or activate things in the UI?

I'm using authentik and I've got:
ACTUAL_OPENID_DISCOVERY_URL
ACTUAL_OPENID_CLIENT_ID
ACTUAL_OPENID_CLIENT_SECRET
ACTUAL_OPENID_SERVER_HOSTNAME
vars set, but I see nothing in the logs, and actual is still prompting for password only. Is there an env var counterpart for authMethod or is actual supposed to infer that by the env vars?

@jsimcina commented on GitHub (Jan 7, 2025): Am I missing something? When trying to set OpenID via env variables, do I need to set a config.json file or activate things in the UI? I'm using authentik and I've got: ACTUAL_OPENID_DISCOVERY_URL ACTUAL_OPENID_CLIENT_ID ACTUAL_OPENID_CLIENT_SECRET ACTUAL_OPENID_SERVER_HOSTNAME vars set, but I see nothing in the logs, and actual is still prompting for password only. Is there an env var counterpart for authMethod or is actual supposed to infer that by the env vars?
Author
Owner

@lelemm commented on GitHub (Jan 7, 2025):

Am I missing something? When trying to set OpenID via env variables, do I need to set a config.json file or activate things in the UI?

I'm using authentik and I've got: ACTUAL_OPENID_DISCOVERY_URL ACTUAL_OPENID_CLIENT_ID ACTUAL_OPENID_CLIENT_SECRET ACTUAL_OPENID_SERVER_HOSTNAME vars set, but I see nothing in the logs, and actual is still prompting for password only. Is there an env var counterpart for authMethod or is actual supposed to infer that by the env vars?

this has being discussed at discord, take a look here:
https://discord.com/channels/937901803608096828/1245792355748155392/1326221059724410901

@lelemm commented on GitHub (Jan 7, 2025): > Am I missing something? When trying to set OpenID via env variables, do I need to set a config.json file or activate things in the UI? > > I'm using authentik and I've got: ACTUAL_OPENID_DISCOVERY_URL ACTUAL_OPENID_CLIENT_ID ACTUAL_OPENID_CLIENT_SECRET ACTUAL_OPENID_SERVER_HOSTNAME vars set, but I see nothing in the logs, and actual is still prompting for password only. Is there an env var counterpart for authMethod or is actual supposed to infer that by the env vars? this has being discussed at discord, take a look here: https://discord.com/channels/937901803608096828/1245792355748155392/1326221059724410901
Author
Owner

@joewashear007 commented on GitHub (Jan 7, 2025):

Thank you very much for this feature! it works great so far! My only comment is the User management menu being hidden behind the "Server Online" button is very non-intuitive and hard to discover. I thought something was broken until I can to this issue and researched it. It a small UI thing, but it definite help.

@joewashear007 commented on GitHub (Jan 7, 2025): **Thank you very much for this feature! it works great so far!** My only comment is the User management menu being hidden behind the "Server Online" button is very non-intuitive and hard to discover. I thought something was broken until I can to this issue and researched it. It a small UI thing, but it definite help.
Author
Owner

@deathblade666 commented on GitHub (Jan 7, 2025):

To test this, I:

1. Created an account on auth0, created a (fake) web app and created a user there. For the callback URL I used https://actual.domain.com:5006/openid/callback.

2. Attempted a sign in with the user I created on auth0 and got an error message. I went back to the login page to try again, and now it logged me in automatically (weird?).

3. I opened a budget file, which worked. But when closing the budget file, it says: "Owner: Unassigned". Another budget file is showing the same, and a third (test) budget file is showing "Owner: Server". I expected the Owner to be the first OpenID user to open the budget file.

First logon is the owner of the server (admin), to my knowledge the budget files are not associated with the server owner aside from being available to serve from the server. I think having them unassigned makes sense especially for the case where people have already been sharing their instance. they can just assign to the appropriate person(s) instead of having to remember to reassign each file

@deathblade666 commented on GitHub (Jan 7, 2025): > To test this, I: > > 1. Created an account on auth0, created a (fake) web app and created a user there. For the callback URL I used https://actual.domain.com:5006/openid/callback. > > 2. Attempted a sign in with the user I created on auth0 and got an error message. I went back to the login page to try again, and now it logged me in automatically (weird?). > > 3. I opened a budget file, which worked. But when closing the budget file, it says: "Owner: Unassigned". Another budget file is showing the same, and a third (test) budget file is showing "Owner: Server". I expected the Owner to be the first OpenID user to open the budget file. First logon is the owner of the server (admin), to my knowledge the budget files are not associated with the server owner aside from being available to serve from the server. I think having them unassigned makes sense especially for the case where people have already been sharing their instance. they can just assign to the appropriate person(s) instead of having to remember to reassign each file
Author
Owner

@lelemm commented on GitHub (Jan 7, 2025):

Just to clarify about the owner naming.

  • Files created BEFORE v24.12.0 will have the owner "Owner: Unassigned", because the concept of owner didn't exist at that time and ownership was NOT migrated to the default user at v24.12.0.
  • Files created DURING v24.12.0 and AFTER (without openid enabled) will have the owner "Server" because the fallback user (that uses the server password) is called "Server"
  • Files created AFTER v25.1.0 when enabling openid will have the OWNER = the openid user.
  • With openid enabled, if you login using the server password and create a file, owner = "Server"

You can change the owner anytime at the user access page. There is a button at the bottom right "Transfer Ownership"

@lelemm commented on GitHub (Jan 7, 2025): Just to clarify about the owner naming. - Files created BEFORE v24.12.0 will have the owner "Owner: Unassigned", because the concept of owner didn't exist at that time and ownership was _NOT_ migrated to the default user at v24.12.0. - Files created DURING v24.12.0 and AFTER (without openid enabled) will have the owner "Server" because the fallback user (that uses the server password) is called "Server" - Files created AFTER v25.1.0 when enabling openid will have the OWNER = the openid user. - With openid enabled, if you login using the server password and create a file, owner = "Server" You can change the owner anytime at the user access page. There is a button at the bottom right "Transfer Ownership"
Author
Owner

@jsimcina commented on GitHub (Jan 7, 2025):

Am I missing something? When trying to set OpenID via env variables, do I need to set a config.json file or activate things in the UI?
I'm using authentik and I've got: ACTUAL_OPENID_DISCOVERY_URL ACTUAL_OPENID_CLIENT_ID ACTUAL_OPENID_CLIENT_SECRET ACTUAL_OPENID_SERVER_HOSTNAME vars set, but I see nothing in the logs, and actual is still prompting for password only. Is there an env var counterpart for authMethod or is actual supposed to infer that by the env vars?

this has being discussed at discord, take a look here: https://discord.com/channels/937901803608096828/1245792355748155392/1326221059724410901

Ahhhh thank you for that. I just joined the discord so I hadn't looked there. That step should probably make it into the docs. I'm running in a K8S container rather than docker, and it's been operating beautifully.

So for anyone else trying to figure this out, the long and short of it is, npm has to be run once within the container to toggle the setting on in order for it to even read the env vars.

I did manage to get it up and running, here are a couple caveats I experienced though:

  • Authentik needs to have a signing key selected, if left without a signing key it will sign the JWT using the client secret using HS256, and evidently the openid library Actual is using only accepts RS256
  • Once that was resolved I attempted to sign in and got a grant fail error, after signing in with the password I was able to create a user for myself using my openid username. Once I did that I was able to sign in successfully with openid, then I was able to transfer ownership.
@jsimcina commented on GitHub (Jan 7, 2025): > > Am I missing something? When trying to set OpenID via env variables, do I need to set a config.json file or activate things in the UI? > > I'm using authentik and I've got: ACTUAL_OPENID_DISCOVERY_URL ACTUAL_OPENID_CLIENT_ID ACTUAL_OPENID_CLIENT_SECRET ACTUAL_OPENID_SERVER_HOSTNAME vars set, but I see nothing in the logs, and actual is still prompting for password only. Is there an env var counterpart for authMethod or is actual supposed to infer that by the env vars? > > this has being discussed at discord, take a look here: https://discord.com/channels/937901803608096828/1245792355748155392/1326221059724410901 Ahhhh thank you for that. I just joined the discord so I hadn't looked there. That step should probably make it into the docs. I'm running in a K8S container rather than docker, and it's been operating beautifully. So for anyone else trying to figure this out, the long and short of it is, npm has to be run once within the container to toggle the setting on in order for it to even read the env vars. I did manage to get it up and running, here are a couple caveats I experienced though: - Authentik needs to have a signing key selected, if left without a signing key it will sign the JWT using the client secret using HS256, and evidently the openid library Actual is using only accepts RS256 - Once that was resolved I attempted to sign in and got a grant fail error, after signing in with the password I was able to create a user for myself using my openid username. Once I did that I was able to sign in successfully with openid, then I was able to transfer ownership.
Author
Owner

@Arnoud-B commented on GitHub (Jan 7, 2025):

Is it expected that basic users cannot link bank accounts? It seems only the admin can link bank accounts now, while I would expect basic users that are owners of the current budget file to also be able to link bank accounts. It's their own budget, after all.

Would be a pain for the admin to manage this for all users too (where every account needs to log in again every 180 days, with the login details of the user and not the admin).

@Arnoud-B commented on GitHub (Jan 7, 2025): Is it expected that basic users cannot link bank accounts? It seems only the admin can link bank accounts now, while I would expect basic users that are owners of the current budget file to also be able to link bank accounts. It's their own budget, after all. Would be a pain for the admin to manage this for all users too (where every account needs to log in again every 180 days, with the login details of the user and not the admin).
Author
Owner

@deathblade666 commented on GitHub (Jan 7, 2025):

Is it expected that basic users cannot link bank accounts? It seems only the admin can link bank accounts now, while I would expect basic users that are owners of the current budget file to also be able to link bank accounts (it's their own budget, after all). Would be a pain for the admin to manage this for all users too (where every account needs to log in again every 180 days, with the login details of the user and not the admin).

lelemm will have to comment on access, but i know as of current if you have bank sync setup it is not per budget. that is to say, the token with the sync provider is set on the server and not associated with the budget files directly.

@deathblade666 commented on GitHub (Jan 7, 2025): > Is it expected that basic users cannot link bank accounts? It seems only the admin can link bank accounts now, while I would expect basic users that are owners of the current budget file to also be able to link bank accounts (it's their own budget, after all). Would be a pain for the admin to manage this for all users too (where every account needs to log in again every 180 days, with the login details of the user and not the admin). lelemm will have to comment on access, but i know as of current if you have bank sync setup it is not per budget. that is to say, the token with the sync provider is set on the server and not associated with the budget files directly.
Author
Owner

@cromelex commented on GitHub (Jan 8, 2025):

Okay I managed to get this working with Authelia, thanks to the above.

For Authelia, I added the following to configuration.yml and then restarted it.

identity_providers:
  oidc:
    ## The other portions of the mandatory OpenID Connect 1.0 configuration go here.
    ## See: https://www.authelia.com/c/oidc
    clients:
    # Actual
      - client_id: 'actualbudget'
        client_name: 'Actual'
        client_secret: ''$pbkdf2-digestedsecret'
        authorization_policy: 'two_factor'
        redirect_uris:
          - 'https://actualbudget.example.com/openid/callback'
        public: false
        require_pkce: true
        pkce_challenge_method: 'S256'
        grant_types:
          - 'authorization_code'
        scopes:
          - 'openid'
          - 'profile'
          - 'groups'
          - 'email'
        userinfo_signed_response_alg: 'none'
        token_endpoint_auth_method: 'client_secret_basic'

For Actual, I had to create the config.json in /data

{
"openId": {
        "issuer": "https://auth.example.com",
        "client_id": "actual",
        "client_secret": "insecure_secret",
        "server_hostname": "https://actualbudget.example.com",
        "authMethod": "oauth2"
    }
}

Then, go into the actualbudget docker container and run

npm run disable-openid #to ensure it was disabled
Then run
npm run enable-openid

I went back into my Actual-Budget instance, logged out and logged back in, selecting the OpenID option. This triggered the request to Authelia and assigned my user as owner for the budget.

Then I added a second user based on this
https://deploy-preview-447.www.actualbudget.org/docs/experimental/multi-user

ie, https://actualbudget.example.com/user-directory and manually added the 2nd user, and the gave them access to the budget via https://actualbudget.example.com//user-access.

Logged in via Authelia with said user successfully.

Seems to be working as intended!

@cromelex commented on GitHub (Jan 8, 2025): Okay I managed to get this working with **Authelia**, thanks to the above. For Authelia, I added the following to configuration.yml and then restarted it. ```yml identity_providers: oidc: ## The other portions of the mandatory OpenID Connect 1.0 configuration go here. ## See: https://www.authelia.com/c/oidc clients: # Actual - client_id: 'actualbudget' client_name: 'Actual' client_secret: ''$pbkdf2-digestedsecret' authorization_policy: 'two_factor' redirect_uris: - 'https://actualbudget.example.com/openid/callback' public: false require_pkce: true pkce_challenge_method: 'S256' grant_types: - 'authorization_code' scopes: - 'openid' - 'profile' - 'groups' - 'email' userinfo_signed_response_alg: 'none' token_endpoint_auth_method: 'client_secret_basic' ``` For Actual, I had to create the `config.json` in /data ```json { "openId": { "issuer": "https://auth.example.com", "client_id": "actual", "client_secret": "insecure_secret", "server_hostname": "https://actualbudget.example.com", "authMethod": "oauth2" } } ``` Then, go into the actualbudget docker container and run `npm run disable-openid` #to ensure it was disabled Then run `npm run enable-openid` I went back into my Actual-Budget instance, logged out and logged back in, selecting the OpenID option. This triggered the request to Authelia and assigned my user as owner for the budget. Then I added a second user based on this https://deploy-preview-447.www.actualbudget.org/docs/experimental/multi-user ie, `https://actualbudget.example.com/user-directory` and manually added the 2nd user, and the gave them access to the budget via `https://actualbudget.example.com//user-access`. Logged in via Authelia with said user successfully. Seems to be working as intended!
Author
Owner

@bennesp commented on GitHub (Jan 8, 2025):

Am I missing something? When trying to set OpenID via env variables, do I need to set a config.json file or activate things in the UI?
I'm using authentik and I've got: ACTUAL_OPENID_DISCOVERY_URL ACTUAL_OPENID_CLIENT_ID ACTUAL_OPENID_CLIENT_SECRET ACTUAL_OPENID_SERVER_HOSTNAME vars set, but I see nothing in the logs, and actual is still prompting for password only. Is there an env var counterpart for authMethod or is actual supposed to infer that by the env vars?

this has being discussed at discord, take a look here: https://discord.com/channels/937901803608096828/1245792355748155392/1326221059724410901

Can we have it documented somewhere? I had to create a discord user, click many "accept" "skip" and so on 😕

To everyone that do not want to create a discord user, the solution is to run the following command inside the container:

npm run enable-openid --prefix /app

Also:
ACTUAL_OPENID_SERVER_HOSTNAME should be actual-ly (🤭) be called ACTUAL_OPENID_SERVER_URL since it requires the schema (https://)

Thank you for the great progress on this feature though!

@bennesp commented on GitHub (Jan 8, 2025): > > Am I missing something? When trying to set OpenID via env variables, do I need to set a config.json file or activate things in the UI? > > I'm using authentik and I've got: ACTUAL_OPENID_DISCOVERY_URL ACTUAL_OPENID_CLIENT_ID ACTUAL_OPENID_CLIENT_SECRET ACTUAL_OPENID_SERVER_HOSTNAME vars set, but I see nothing in the logs, and actual is still prompting for password only. Is there an env var counterpart for authMethod or is actual supposed to infer that by the env vars? > > this has being discussed at discord, take a look here: https://discord.com/channels/937901803608096828/1245792355748155392/1326221059724410901 Can we have it documented somewhere? I had to create a discord user, click many "accept" "skip" and so on 😕 To everyone that do not want to create a discord user, the solution is to run the following command inside the container: ``` npm run enable-openid --prefix /app ``` Also: `ACTUAL_OPENID_SERVER_HOSTNAME` should be actual-ly (🤭) be called `ACTUAL_OPENID_SERVER_URL` since it requires the schema (`https://`) Thank you for the great progress on this feature though!
Author
Owner

@hendrik1120 commented on GitHub (Jan 8, 2025):

Hi, I am happy to see the ongoing development of actualbudget and the new addition of SSO using OIDC and OAuth2.0.

I have tested the OpenID feature using the WebUI with Authelia. I get the following error:

{"status":"error","reason":"openid-grant-failed"}
2025-01-08T17:23:08.575Z info: GET 400 /openid/callback?code=authelia_ac_<redacted>&iss=https%3A%2F%2Fauth.example.com&scope=openid+email+profile&state=2gbbP-UK8xj2Gs2pcfRnI724JWRzgTIw_3YSqxqIP7c
OpenID grant failed: RPError: iss missing from the response
    at Client.callback (/app/node_modules/openid-client/lib/client.js:436:13)
    at loginWithOpenIdFinalize (file:///app/src/accounts/openid.js:177:31)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async file:///app/src/app-openid.js:86:24 {
  params: {
    code: 'authelia_ac_<redacted>',
    state: '2gbbP-UK8xj2Gs2pcfRnI724JWRzgTIw_3YSqxqIP7c'
  }
}

To me, this looks like actual is expecting the iss (issuer) parameter to be present in the Authentication Response. However the iss parameter is not required to be present in the response by section 3.1.2.5 of the openid standard or section 4.1.2 of the oauth2.0 standard. Authelia correctly encodes the iss parameter in the IDToken as required.

Actually authelia supports RFC9207 which basically only implements the iss parameter in the Authrization Response. However there must be some sort of issue either in the library used or the implementation where the iss validation fails. The parameter is included in the authelia response:

https://actual.example.com/openid/callback?code=authelia_ac_<redacted>&iss=https%3A%2F%2Fauth.example.com&scope=openid+email+profile&state=2gbbP-UK8xj2Gs2pcfRnI724JWRzgTIw_3YSqxqIP7c

It is possible that I interpreted the error wrong, but I think this might be a bug.

Authelia oidc client configuration for reference:

identity_providers:
  oidc:
    clients:
      - client_id: 'actual'
        client_name: 'actual'
        client_secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng'  # The digest of 'insecure_secret'.
        public: false
        require_pkce: true
        pkce_challenge_method: 'S256'
        authorization_policy: 'two_factor'
        redirect_uris:
          - 'https://actual.example.com/openid/callback'
        scopes:
          - 'openid'
          - 'profile'
          - 'email'
        userinfo_signed_response_alg: 'none'
@hendrik1120 commented on GitHub (Jan 8, 2025): Hi, I am happy to see the ongoing development of actualbudget and the new addition of SSO using OIDC and OAuth2.0. I have tested the OpenID feature using the WebUI with Authelia. I get the following error: ```json {"status":"error","reason":"openid-grant-failed"} ``` ``` 2025-01-08T17:23:08.575Z info: GET 400 /openid/callback?code=authelia_ac_<redacted>&iss=https%3A%2F%2Fauth.example.com&scope=openid+email+profile&state=2gbbP-UK8xj2Gs2pcfRnI724JWRzgTIw_3YSqxqIP7c OpenID grant failed: RPError: iss missing from the response at Client.callback (/app/node_modules/openid-client/lib/client.js:436:13) at loginWithOpenIdFinalize (file:///app/src/accounts/openid.js:177:31) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async file:///app/src/app-openid.js:86:24 { params: { code: 'authelia_ac_<redacted>', state: '2gbbP-UK8xj2Gs2pcfRnI724JWRzgTIw_3YSqxqIP7c' } } ``` To me, this looks like actual is expecting the `iss` (issuer) parameter to be present in the Authentication Response. ~~However the `iss` parameter is not required to be present in the response by section 3.1.2.5 of the [openid standard](https://openid.net/specs/openid-connect-core-1_0.html#AuthResponse) or section 4.1.2 of the [oauth2.0 standard](https://www.rfc-editor.org/rfc/rfc6749.html#section-4.1.2). Authelia correctly encodes the `iss` parameter in the [IDToken](https://openid.net/specs/openid-connect-core-1_0.html#IDToken) as required.~~ Actually authelia supports [RFC9207](https://datatracker.ietf.org/doc/html/rfc9207) which basically only implements the `iss` parameter in the Authrization Response. However there must be some sort of issue either in the library used or the implementation where the `iss` validation fails. The parameter is included in the authelia response: ``` https://actual.example.com/openid/callback?code=authelia_ac_<redacted>&iss=https%3A%2F%2Fauth.example.com&scope=openid+email+profile&state=2gbbP-UK8xj2Gs2pcfRnI724JWRzgTIw_3YSqxqIP7c ``` It is possible that I interpreted the error wrong, but I think this might be a bug. Authelia oidc client configuration for reference: ```yaml identity_providers: oidc: clients: - client_id: 'actual' client_name: 'actual' client_secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng' # The digest of 'insecure_secret'. public: false require_pkce: true pkce_challenge_method: 'S256' authorization_policy: 'two_factor' redirect_uris: - 'https://actual.example.com/openid/callback' scopes: - 'openid' - 'profile' - 'email' userinfo_signed_response_alg: 'none' ```
Author
Owner

@ilovepancakes95 commented on GitHub (Jan 8, 2025):

I was able to setup OpenID Auth using Synology DSM SSO Server with their OIDC feature enabled. I can login to Actual, etc. however what doesn't seem to be working is the setting of the "Server Owner" when the first account logs in after OIDC is enabled. I can see my user in User Directory but there is no check mark next to Server Owner. This causes the warning to still appear on the login page about server owner being set to first user and it also is preventing the regular password login from being disabled.

Any ideas why the server owner isn't be set automatically to first user to login (me) after OIDC setup is enabled, and is there anyway to force set the server owner now... I tried clearing cookies and restarting the docker container and signing in from scratch, didn't help.

@ilovepancakes95 commented on GitHub (Jan 8, 2025): I was able to setup OpenID Auth using Synology DSM SSO Server with their OIDC feature enabled. I can login to Actual, etc. however what doesn't seem to be working is the setting of the "Server Owner" when the first account logs in after OIDC is enabled. I can see my user in User Directory but there is no check mark next to Server Owner. This causes the warning to still appear on the login page about server owner being set to first user and it also is preventing the regular password login from being disabled. Any ideas why the server owner isn't be set automatically to first user to login (me) after OIDC setup is enabled, and is there anyway to force set the server owner now... I tried clearing cookies and restarting the docker container and signing in from scratch, didn't help.
Author
Owner

@DennaGherlyn commented on GitHub (Jan 8, 2025):

[...] it also is preventing the regular password login from being disabled.

Can you even disable the regular password? I'm Server Owner but I still have the option to use the password. And I don't see any settings for that either. I would guess that deactivating the password option is not a thing yet.

@DennaGherlyn commented on GitHub (Jan 8, 2025): > [...] it also is preventing the regular password login from being disabled. Can you even disable the regular password? I'm Server Owner but I still have the option to use the password. And I don't see any settings for that either. I would guess that deactivating the password option is not a thing yet.
Author
Owner

@ilovepancakes95 commented on GitHub (Jan 8, 2025):

[...] it also is preventing the regular password login from being disabled.

Can you even disable the regular password? I'm Server Owner but I still have the option to use the password. And I don't see any settings for that either. I would guess that deactivating the password option is not a thing yet.

Hmm, I was under the impression that once a server owner is set after the first OIDC login happens that it disables regular password based access and goes into multi-user mode only. Maybe I misunderstood, and can't test because my install isn't properly setting server owner by itself anyway and getting rid of the ability to edit OIDC settings before login. So right now, anybody could just edit OIDC settings to their own provider and get in.

@ilovepancakes95 commented on GitHub (Jan 8, 2025): > > [...] it also is preventing the regular password login from being disabled. > > Can you even disable the regular password? I'm Server Owner but I still have the option to use the password. And I don't see any settings for that either. I would guess that deactivating the password option is not a thing yet. Hmm, I was under the impression that once a server owner is set after the first OIDC login happens that it disables regular password based access and goes into multi-user mode only. Maybe I misunderstood, and can't test because my install isn't properly setting server owner by itself anyway and getting rid of the ability to edit OIDC settings before login. So right now, anybody could just edit OIDC settings to their own provider and get in.
Author
Owner

@DennaGherlyn commented on GitHub (Jan 8, 2025):

[...] it also is preventing the regular password login from being disabled.

Can you even disable the regular password? I'm Server Owner but I still have the option to use the password. And I don't see any settings for that either. I would guess that deactivating the password option is not a thing yet.

Hmm, I was under the impression that once a server owner is set after the first OIDC login happens that it disables regular password based access and goes into multi-user mode only. Maybe I misunderstood, and can't test because my install isn't properly setting server owner by itself anyway and getting rid of the ability to edit OIDC settings before login. So right now, anybody could just edit OIDC settings to their own provider and get in.

Okay, so. I finally managed to get onto Discord (it was very stubborn today) and there lelemm said that disabling the password is not possible because the API needs it and auto-login is not available yet.

@DennaGherlyn commented on GitHub (Jan 8, 2025): > > > [...] it also is preventing the regular password login from being disabled. > > > > > > Can you even disable the regular password? I'm Server Owner but I still have the option to use the password. And I don't see any settings for that either. I would guess that deactivating the password option is not a thing yet. > > Hmm, I was under the impression that once a server owner is set after the first OIDC login happens that it disables regular password based access and goes into multi-user mode only. Maybe I misunderstood, and can't test because my install isn't properly setting server owner by itself anyway and getting rid of the ability to edit OIDC settings before login. So right now, anybody could just edit OIDC settings to their own provider and get in. Okay, so. I finally managed to get onto Discord (it was very stubborn today) and there lelemm said that disabling the password is not possible because the API needs it and auto-login is not available yet.
Author
Owner

@ilovepancakes95 commented on GitHub (Jan 8, 2025):

[...] it also is preventing the regular password login from being disabled.

Can you even disable the regular password? I'm Server Owner but I still have the option to use the password. And I don't see any settings for that either. I would guess that deactivating the password option is not a thing yet.

Hmm, I was under the impression that once a server owner is set after the first OIDC login happens that it disables regular password based access and goes into multi-user mode only. Maybe I misunderstood, and can't test because my install isn't properly setting server owner by itself anyway and getting rid of the ability to edit OIDC settings before login. So right now, anybody could just edit OIDC settings to their own provider and get in.

Okay, so. I finally managed to get onto Discord (it was very stubborn today) and there lelemm said that disabling the password is not possible because the API needs it and auto-login is not available yet.

OK if that is the case, then it seems the only downside to my situation is without a server owner being set, anyone coming upon the login page can now change the OIDC settings to their own provider and then login. Obviously this prevents me from "launching" using this yet, completely not secure.

@ilovepancakes95 commented on GitHub (Jan 8, 2025): > > > > [...] it also is preventing the regular password login from being disabled. > > > > > > > > > Can you even disable the regular password? I'm Server Owner but I still have the option to use the password. And I don't see any settings for that either. I would guess that deactivating the password option is not a thing yet. > > > > > > Hmm, I was under the impression that once a server owner is set after the first OIDC login happens that it disables regular password based access and goes into multi-user mode only. Maybe I misunderstood, and can't test because my install isn't properly setting server owner by itself anyway and getting rid of the ability to edit OIDC settings before login. So right now, anybody could just edit OIDC settings to their own provider and get in. > > Okay, so. I finally managed to get onto Discord (it was very stubborn today) and there lelemm said that disabling the password is not possible because the API needs it and auto-login is not available yet. OK if that is the case, then it seems the only downside to my situation is without a server owner being set, anyone coming upon the login page can now change the OIDC settings to their own provider and then login. Obviously this prevents me from "launching" using this yet, completely not secure.
Author
Owner

@shall0pass commented on GitHub (Jan 8, 2025):

If you're referring to the link to change the OIDC settings on the login page, that link disappears once you login using openid.... at least it did for me.

I too would welcome an option (probably an environment option in the compose file that is easy to change before spinning up a container) to disable the web page password prompt. I do understand not totally locking it out for the API to continue to have access.

@shall0pass commented on GitHub (Jan 8, 2025): If you're referring to the link to change the OIDC settings on the login page, that link disappears once you login using openid.... at least it did for me. I too would welcome an option (probably an environment option in the compose file that is easy to change before spinning up a container) to disable the web page password prompt. I do understand not totally locking it out for the API to continue to have access.
Author
Owner

@ilovepancakes95 commented on GitHub (Jan 8, 2025):

If you're referring to the link to change the OIDC settings on the login page, that link disappears once you login using openid.... at least it did for me.

That is exactly what I mean. On my system, I get that prompt, I sign-in, but after I log out, the prompt is still there and I (or anyone else) can still change OIDC settings. And when I do login, under User Directory, my user (or any user) is not checked as "System Owner". Like whatever process that sets the system owner isn't working.

Hoping there is an easy quick fix.

@ilovepancakes95 commented on GitHub (Jan 8, 2025): > If you're referring to the link to change the OIDC settings on the login page, that link disappears once you login using openid.... at least it did for me. That is exactly what I mean. On my system, I get that prompt, I sign-in, but after I log out, the prompt is still there and I (or anyone else) can still change OIDC settings. And when I do login, under User Directory, my user (or any user) is not checked as "System Owner". Like whatever process that sets the system owner isn't working. Hoping there is an easy quick fix.
Author
Owner

@lelemm commented on GitHub (Jan 8, 2025):

If you're referring to the link to change the OIDC settings on the login page, that link disappears once you login using openid.... at least it did for me.

That is exactly what I mean. On my system, I get that prompt, I sign-in, but after I log out, the prompt is still there and I (or anyone else) can still change OIDC settings. And when I do login, under User Directory, my user (or any user) is not checked as "System Owner". Like whatever process that sets the system owner isn't working.

Hoping there is an easy quick fix.

you probably had an error but somehow the flow went until the end so you system owner was never created. I highly suggest you to disable openid and enable again to check for errors and to be sure the system owner is created

@lelemm commented on GitHub (Jan 8, 2025): > > If you're referring to the link to change the OIDC settings on the login page, that link disappears once you login using openid.... at least it did for me. > > That is exactly what I mean. On my system, I get that prompt, I sign-in, but after I log out, the prompt is still there and I (or anyone else) can still change OIDC settings. And when I do login, under User Directory, my user (or any user) is not checked as "System Owner". Like whatever process that sets the system owner isn't working. > > Hoping there is an easy quick fix. you probably had an error but somehow the flow went until the end so you system owner was never created. I highly suggest you to disable openid and enable again to check for errors and to be sure the system owner is created
Author
Owner

@ilovepancakes95 commented on GitHub (Jan 9, 2025):

you probably had an error but somehow the flow went until the end so you system owner was never created. I highly suggest you to disable openid and enable again to check for errors and to be sure the system owner is created

Think you are right. If I disable OIDC and then re-enable and go throw the flow from scratch I get {"status":"error","reason":"user-already-exists"} as the error in the web browser immediately after clicking "Sign In with Open ID".

@ilovepancakes95 commented on GitHub (Jan 9, 2025): > you probably had an error but somehow the flow went until the end so you system owner was never created. I highly suggest you to disable openid and enable again to check for errors and to be sure the system owner is created Think you are right. If I disable OIDC and then re-enable and go throw the flow from scratch I get `{"status":"error","reason":"user-already-exists"}` as the error in the web browser immediately after clicking "Sign In with Open ID".
Author
Owner

@lelemm commented on GitHub (Jan 9, 2025):

you probably had an error but somehow the flow went until the end so you system owner was never created. I highly suggest you to disable openid and enable again to check for errors and to be sure the system owner is created

Think you are right. If I disable OIDC and then re-enable and go throw the flow from scratch I get {"status":"error","reason":"user-already-exists"} as the error in the web browser immediately after clicking "Sign In with Open ID".

I guess the username returned by the provider is empty string.
because there is a empty username string in the server (the fallback server password user has empty username)

@lelemm commented on GitHub (Jan 9, 2025): > > you probably had an error but somehow the flow went until the end so you system owner was never created. I highly suggest you to disable openid and enable again to check for errors and to be sure the system owner is created > > Think you are right. If I disable OIDC and then re-enable and go throw the flow from scratch I get `{"status":"error","reason":"user-already-exists"}` as the error in the web browser immediately after clicking "Sign In with Open ID". I guess the username returned by the provider is empty string. because there is a empty username string in the server (the fallback server password user has empty username)
Author
Owner

@hendrik1120 commented on GitHub (Jan 9, 2025):

I have updated my initial bug report with additional information for troubleshooting. I still believe this a bug in the actualbudget oidc client.

@hendrik1120 commented on GitHub (Jan 9, 2025): I have updated my [initial bug report](https://github.com/actualbudget/actual/issues/4029#issuecomment-2578290735) with additional information for troubleshooting. I still believe this a bug in the actualbudget oidc client.
Author
Owner

@nicedevil007 commented on GitHub (Jan 9, 2025):

hey guys, just a small thing for you => authentik is written with a lowercase "a". Can you change this on the dropdown menu for the openID provider? I'm already on my PR for the documentation of authentik's official page and the guys that are reviewing my PR already told this to me :)

https://github.com/goauthentik/authentik/pull/12590#discussion_r1909137417

I mean this part here during the configuration:
image

@nicedevil007 commented on GitHub (Jan 9, 2025): hey guys, just a small thing for you => authentik is written with a lowercase "a". Can you change this on the dropdown menu for the openID provider? I'm already on my PR for the documentation of authentik's official page and the guys that are reviewing my PR already told this to me :) https://github.com/goauthentik/authentik/pull/12590#discussion_r1909137417 I mean this part here during the configuration: ![image](https://github.com/user-attachments/assets/7a120e46-8db7-4d91-b5ee-035daf41d17d)
Author
Owner

@tugdualenligne commented on GitHub (Jan 11, 2025):

I there, just wanted to say thanks!
And that OpenID set-up worked fine for me using Authentik 24.12.2
It should be precised though, that the Redirect URI should be https://actual.domain.tld/openid/callback
And that you cannot chose as an Encryption key the "Authentik self-signed certificate" as it doesn't work if you do

@tugdualenligne commented on GitHub (Jan 11, 2025): I there, just wanted to say thanks! And that OpenID set-up worked fine for me using Authentik 24.12.2 It should be precised though, that the Redirect URI should be https://_actual.domain.tld_/openid/callback And that you cannot chose as an Encryption key the "Authentik self-signed certificate" as it doesn't work if you do
Author
Owner

@savely-krasovsky commented on GitHub (Jan 12, 2025):

Configured with Casdoor, works without any issues for me.

@savely-krasovsky commented on GitHub (Jan 12, 2025): Configured with [Casdoor](https://github.com/casdoor/casdoor), works without any issues for me.
Author
Owner

@ajf15cc commented on GitHub (Jan 12, 2025):

Just want to say thank you to all who were involved with developing this, seriously useful now that partner and I can share a single budget.

Just to add, due to issues with Entra / Azure AD using the Display Name (rather than the UPN or username), I've configured with Cloudflare Access OIDC as the IDP and it works perfectly!

Thanks Again!

@ajf15cc commented on GitHub (Jan 12, 2025): Just want to say thank you to all who were involved with developing this, seriously useful now that partner and I can share a single budget. Just to add, due to issues with Entra / Azure AD using the Display Name (rather than the UPN or username), I've configured with Cloudflare Access OIDC as the IDP and it works perfectly! Thanks Again!
Author
Owner

@marouamghar commented on GitHub (Jan 14, 2025):

Hey, just to add, it works great in my setup using the config workaround with Authelia.

However, I tried to disable all but opened using allowedLoginMethods in the config file, but it's not picked/applied. I can still login with either the password or openid. Is that behaviour wanted, at least for the experimental phase?

@marouamghar commented on GitHub (Jan 14, 2025): Hey, just to add, it works great in my setup using the config workaround with Authelia. However, I tried to disable all but opened using allowedLoginMethods in the config file, but it's not picked/applied. I can still login with either the password or openid. Is that behaviour wanted, at least for the experimental phase?
Author
Owner

@bobokun commented on GitHub (Jan 16, 2025):

Not sure if you're aware but it could be something related to the openID/multi-user integration that was introduced caused header auth to be broken in v25.1.0

@bobokun commented on GitHub (Jan 16, 2025): Not sure if you're aware but it could be something related to the openID/multi-user integration that was introduced caused [header auth to be broken in v25.1.0](https://discord.com/channels/937901803608096828/1326262567605375038)
Author
Owner

@NateMcKenzie commented on GitHub (Jan 18, 2025):

This is a great feature! My brother and I have self-hosted individual instances of Actual so that we can each have separate budgets. That's not a huge deal, but it is nice to just have one instance. This feature almost gets us there, but it seems like there is only one SimpleFIN token for the whole instsance, so we couldn't use separate SimpleFIN accounts. Is this correct? Are there any plans to say let each user have their own token?

@NateMcKenzie commented on GitHub (Jan 18, 2025): This is a great feature! My brother and I have self-hosted individual instances of Actual so that we can each have separate budgets. That's not a huge deal, but it is nice to just have one instance. This feature almost gets us there, but it seems like there is only one SimpleFIN token for the whole instsance, so we couldn't use separate SimpleFIN accounts. Is this correct? Are there any plans to say let each user have their own token?
Author
Owner

@helloWorld44-89 commented on GitHub (Jan 19, 2025):

I have a similar issue as OP. I am using authentik and my account work as intended. I then tried to login as my wife’s account and got {"status":"error","reason":"openid-grant-failed"}. I checked and no user was created for the login.

Logs for actual budget server:
2025-01-18T23:35:50.199Z info: GET 200 /admin/owner-created/
2025-01-18T23:35:57.068Z info: GET 200 /account/needs-bootstrap
2025-01-18T23:35:57.097Z info: GET 200 /account/needs-bootstrap
2025-01-18T23:35:57.117Z info: GET 200 /account/needs-bootstrap
2025-01-18T23:35:57.158Z info: GET 200 /admin/owner-created/
Logging in via openid
2025-01-18T23:36:00.111Z info: POST 200 /account/login
2025-01-18T23:36:02.549Z info: GET 400 /openid/callback?code=4bec1426c3664e20977da978e750e693&state=HH-1bO-teG2MRKTXeiSSXvKv2y5vDgf40veduVCio8M
Logging in via openid
2025-01-18T23:41:47.867Z info: POST 200 /account/login
2025-01-18T23:41:50.388Z info: GET 400 /openid/callback?code=97bb298a0ccb45c3bd9006993019f9ab&state=azBkGiaWgKUnmJxdH5udZHMew37xpWm0ayHwOTZPzfo

UPDATE: I solved the issue. I had to create the user in Actual prior to them logging in.

Will the open id not create the new user?

@helloWorld44-89 commented on GitHub (Jan 19, 2025): I have a similar issue as OP. I am using authentik and my account work as intended. I then tried to login as my wife’s account and got {"status":"error","reason":"openid-grant-failed"}. I checked and no user was created for the login. Logs for actual budget server: 2025-01-18T23:35:50.199Z info: GET 200 /admin/owner-created/ 2025-01-18T23:35:57.068Z info: GET 200 /account/needs-bootstrap 2025-01-18T23:35:57.097Z info: GET 200 /account/needs-bootstrap 2025-01-18T23:35:57.117Z info: GET 200 /account/needs-bootstrap 2025-01-18T23:35:57.158Z info: GET 200 /admin/owner-created/ Logging in via openid 2025-01-18T23:36:00.111Z info: POST 200 /account/login 2025-01-18T23:36:02.549Z info: GET 400 /openid/callback?code=4bec1426c3664e20977da978e750e693&state=HH-1bO-teG2MRKTXeiSSXvKv2y5vDgf40veduVCio8M Logging in via openid 2025-01-18T23:41:47.867Z info: POST 200 /account/login 2025-01-18T23:41:50.388Z info: GET 400 /openid/callback?code=97bb298a0ccb45c3bd9006993019f9ab&state=azBkGiaWgKUnmJxdH5udZHMew37xpWm0ayHwOTZPzfo UPDATE: I solved the issue. I had to create the user in Actual prior to them logging in. Will the open id not create the new user?
Author
Owner

@RubenOlsen commented on GitHub (Jan 19, 2025):

On the UX side of the Enable OpenID dialog box I believe we should add a sentence saying that people must export their data before continuing. I am aware that there are no technical reason for this, but it's all about 1) making people feel safe; 2) reducing the number of potential support request on the variant of I enabled OpenID - now my data is lost.

Image
@RubenOlsen commented on GitHub (Jan 19, 2025): On the UX side of the Enable OpenID dialog box I believe we should add a sentence saying that people **must** export their data before continuing. I am aware that there are no _technical reason_ for this, but it's all about 1) making people feel safe; 2) reducing the number of potential support request on the variant of _I enabled OpenID - now my data is lost_. <img width="877" alt="Image" src="https://github.com/user-attachments/assets/c9c602e6-41e5-4160-b82b-20357c9443b3" />
Author
Owner

@deathblade666 commented on GitHub (Jan 19, 2025):

I have a similar issue as OP. I am using authentik and my account work as intended. I then tried to login as my wife’s account and got {"status":"error","reason":"openid-grant-failed"}. I checked and no user was created for the login.

Logs for actual budget server: 2025-01-18T23:35:50.199Z info: GET 200 /admin/owner-created/ 2025-01-18T23:35:57.068Z info: GET 200 /account/needs-bootstrap 2025-01-18T23:35:57.097Z info: GET 200 /account/needs-bootstrap 2025-01-18T23:35:57.117Z info: GET 200 /account/needs-bootstrap 2025-01-18T23:35:57.158Z info: GET 200 /admin/owner-created/ Logging in via openid 2025-01-18T23:36:00.111Z info: POST 200 /account/login 2025-01-18T23:36:02.549Z info: GET 400 /openid/callback?code=4bec1426c3664e20977da978e750e693&state=HH-1bO-teG2MRKTXeiSSXvKv2y5vDgf40veduVCio8M Logging in via openid 2025-01-18T23:41:47.867Z info: POST 200 /account/login 2025-01-18T23:41:50.388Z info: GET 400 /openid/callback?code=97bb298a0ccb45c3bd9006993019f9ab&state=azBkGiaWgKUnmJxdH5udZHMew37xpWm0ayHwOTZPzfo

UPDATE: I solved the issue. I had to create the user in Actual prior to them logging in.

Will the open id not create the new user?

OpenID at this time does not create the user accounts within actual so they need to be created manually

@deathblade666 commented on GitHub (Jan 19, 2025): > I have a similar issue as OP. I am using authentik and my account work as intended. I then tried to login as my wife’s account and got {"status":"error","reason":"openid-grant-failed"}. I checked and no user was created for the login. > > Logs for actual budget server: 2025-01-18T23:35:50.199Z info: GET 200 /admin/owner-created/ 2025-01-18T23:35:57.068Z info: GET 200 /account/needs-bootstrap 2025-01-18T23:35:57.097Z info: GET 200 /account/needs-bootstrap 2025-01-18T23:35:57.117Z info: GET 200 /account/needs-bootstrap 2025-01-18T23:35:57.158Z info: GET 200 /admin/owner-created/ Logging in via openid 2025-01-18T23:36:00.111Z info: POST 200 /account/login 2025-01-18T23:36:02.549Z info: GET 400 /openid/callback?code=4bec1426c3664e20977da978e750e693&state=HH-1bO-teG2MRKTXeiSSXvKv2y5vDgf40veduVCio8M Logging in via openid 2025-01-18T23:41:47.867Z info: POST 200 /account/login 2025-01-18T23:41:50.388Z info: GET 400 /openid/callback?code=97bb298a0ccb45c3bd9006993019f9ab&state=azBkGiaWgKUnmJxdH5udZHMew37xpWm0ayHwOTZPzfo > > UPDATE: I solved the issue. I had to create the user in Actual prior to them logging in. > > Will the open id not create the new user? OpenID at this time does not create the user accounts within actual so they need to be created manually
Author
Owner

@deathblade666 commented on GitHub (Jan 19, 2025):

On the UX side of the Enable OpenID dialog box I believe we should add a sentence saying that people must export their data before continuing. I am aware that there are no technical reason for this, but it's all about 1) making people feel safe; 2) reducing the number of potential support request on the variant of I enabled OpenID - now my data is lost.

Image

on that thought, why wouldn't we have it for every experimental feature? and could even go a step further to create a flow that steps people through backing up their data?

@deathblade666 commented on GitHub (Jan 19, 2025): > On the UX side of the Enable OpenID dialog box I believe we should add a sentence saying that people **must** export their data before continuing. I am aware that there are no _technical reason_ for this, but it's all about 1) making people feel safe; 2) reducing the number of potential support request on the variant of _I enabled OpenID - now my data is lost_. > > <img alt="Image" width="877" src="https://private-user-images.githubusercontent.com/318691/404668872-c9c602e6-41e5-4160-b82b-20357c9443b3.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzcyOTY4NTEsIm5iZiI6MTczNzI5NjU1MSwicGF0aCI6Ii8zMTg2OTEvNDA0NjY4ODcyLWM5YzYwMmU2LTQxZTUtNDE2MC1iODJiLTIwMzU3Yzk0NDNiMy5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjUwMTE5JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI1MDExOVQxNDIyMzFaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT1hOTc1NWI2Y2JlOWQ1MWJkYTQ2YTExNjNiZTJiMThiNzU5MTk4ZTIwM2FkMWQ3Mjc0Y2MwZmQ0NTIzZDM4ZDk3JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.EvTPEdoHj7cDoNn-pxPxMzeesEviK6YWr43gdwfdcH0"> on that thought, why wouldn't we have it for every experimental feature? and could even go a step further to create a flow that steps people through backing up their data?
Author
Owner

@UncleArya commented on GitHub (Jan 19, 2025):

Hello. Thank you so much for implementing an OIDC login. I have been switching as many services as I can over to Pocket ID and I got it setup with Actual Budget and was able to login without issue first try. Initial setup was very easy and straightforward.

The only issue I am now facing is when I open the User Directory and attempt to add a new user for my partner manually (as reading higher in this thread I see OIDC can't create a new user yet). I am getting an error that states:
Image
It prevents me from adding a new user. I have recreated the image and restarted the container, without success.

I added OIDC login via GUI and have the following environment variables set in my compose file:

ACTUAL_OPENID_DISCOVERY_URL: https://<MYURL>.well-known/openid-configuration
ACTUAL_OPENID_CLIENT_ID: <VALUE>
ACTUAL_OPENID_CLIENT_SECRET: <VALUE>
ACTUAL_OPENID_SERVER_HOSTNAME: https://actual.budget.tld

Client version: v25.1.0
Server version: v25.1.0
Image: sha-45d53ff-alpine

@UncleArya commented on GitHub (Jan 19, 2025): Hello. Thank you so much for implementing an OIDC login. I have been switching as many services as I can over to Pocket ID and I got it setup with Actual Budget and was able to login without issue first try. Initial setup was very easy and straightforward. The only issue I am now facing is when I open the User Directory and attempt to add a new user for my partner manually (as reading higher in this thread I see OIDC can't create a new user yet). I am getting an error that states: ![Image](https://github.com/user-attachments/assets/ad08b652-17a3-40da-a9c3-fc53568d0682) It prevents me from adding a new user. I have recreated the image and restarted the container, without success. I added OIDC login via GUI and have the following environment variables set in my compose file: ``` ACTUAL_OPENID_DISCOVERY_URL: https://<MYURL>.well-known/openid-configuration ACTUAL_OPENID_CLIENT_ID: <VALUE> ACTUAL_OPENID_CLIENT_SECRET: <VALUE> ACTUAL_OPENID_SERVER_HOSTNAME: https://actual.budget.tld ``` Client version: v25.1.0 Server version: v25.1.0 Image: sha-45d53ff-alpine
Author
Owner

@Mikhail773 commented on GitHub (Jan 19, 2025):

Hello, thank you for all the hard work that was put into openid. I noticed an interesting bug/issue:
When having openid setup it would be expected that each Budget would be able to set up their own simplefin account linking. Instead if you have multiple budgets/accounts each budget will be using the same simple fin token. This means that personal sharing info will be shared between users/budgets. I'm not certain what the solution is, but I would imagine there would need to be a dedicated simplefin/gocardless for each budget/user

@Mikhail773 commented on GitHub (Jan 19, 2025): Hello, thank you for all the hard work that was put into openid. I noticed an interesting bug/issue: When having openid setup it would be expected that each Budget would be able to set up their own simplefin account linking. Instead if you have multiple budgets/accounts each budget will be using the same simple fin token. This means that personal sharing info will be shared between users/budgets. I'm not certain what the solution is, but I would imagine there would need to be a dedicated simplefin/gocardless for each budget/user
Author
Owner

@Frankynov commented on GitHub (Jan 23, 2025):

Hi,
Just a note to let you know that I was able to setup the openID connection with Authentik, without any issue :)
Thanks a lot for the hard work !

@Frankynov commented on GitHub (Jan 23, 2025): Hi, Just a note to let you know that I was able to setup the openID connection with Authentik, without any issue :) Thanks a lot for the hard work !
Author
Owner

@ezcafe commented on GitHub (Jan 26, 2025):

Hi team,
I'm using pocket-id with this config

Name: actual-budget
Callback URLs: https://actual.budget.tld/openid-cb

When login to pocket-id, it shows this error

Invalid callback URL, it might be necessary for an admin to fix this. Please try again.

Is the Callback URLs correct? Which callback url should I use?

Image

Image

@ezcafe commented on GitHub (Jan 26, 2025): Hi team, I'm using pocket-id with this config Name: `actual-budget` Callback URLs: `https://actual.budget.tld/openid-cb` When login to pocket-id, it shows this error `Invalid callback URL, it might be necessary for an admin to fix this. Please try again.` Is the Callback URLs correct? Which callback url should I use? ![Image](https://github.com/user-attachments/assets/f8c40149-d4ec-445b-a9c8-9f71f4ae3624) ![Image](https://github.com/user-attachments/assets/bc5748af-3d3f-493c-9fcf-51b9c47feb3b)
Author
Owner

@savely-krasovsky commented on GitHub (Jan 26, 2025):

@ezcafe you should set this: https://actual.budget.tld/openid/callback

@savely-krasovsky commented on GitHub (Jan 26, 2025): @ezcafe you should set this: https://actual.budget.tld/openid/callback
Author
Owner

@ezcafe commented on GitHub (Jan 26, 2025):

It's working now. Thanks @savely-krasovsky

@ezcafe commented on GitHub (Jan 26, 2025): It's working now. Thanks @savely-krasovsky
Author
Owner

@tr-io commented on GitHub (Jan 26, 2025):

Hi, I'm trying to setup OpenID with Authentik in the ActualBudget UI and I'm running into the following error:

actual_server-1  | 2025-01-26T19:34:34.328Z info: POST 500 /openid/enable
actual_server-1  | Error setting up OpenID client: Error: unable to get local issuer certificate
actual_server-1  |     at TLSSocket.onConnectSecure (node:_tls_wrap:1659:34)
actual_server-1  |     at TLSSocket.emit (node:events:517:28)
actual_server-1  |     at TLSSocket._finishInit (node:_tls_wrap:1070:8)
actual_server-1  |     at ssl.onhandshakedone (node:_tls_wrap:856:12) {
actual_server-1  |   code: 'UNABLE_TO_GET_ISSUER_CERT_LOCALLY'
actual_server-1  | }

I have a custom internal domain and I'm using Caddy as a reverse proxy. I've had similar issues with other selfhosted apps which were resolved by adding the custom certs to those containers. I've tried adding the following to a Dockerfile:

FROM docker.io/actualbudget/actual-server:latest

COPY ca-certificates.crt /opt/ca-certificates.crt
RUN apt-get update && apt-get install -y ca-certificates
RUN update-ca-certificates

And I've also tried the ca-certificates.ca as a volume in the docker-compose.yml file:

...
- /opt/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt
...

I'm not too familiar with node so I'm probably adding the certs incorrectly? My authentik domain is https://authentik.customdomain

@tr-io commented on GitHub (Jan 26, 2025): Hi, I'm trying to setup OpenID with Authentik in the ActualBudget UI and I'm running into the following error: ``` actual_server-1 | 2025-01-26T19:34:34.328Z info: POST 500 /openid/enable actual_server-1 | Error setting up OpenID client: Error: unable to get local issuer certificate actual_server-1 | at TLSSocket.onConnectSecure (node:_tls_wrap:1659:34) actual_server-1 | at TLSSocket.emit (node:events:517:28) actual_server-1 | at TLSSocket._finishInit (node:_tls_wrap:1070:8) actual_server-1 | at ssl.onhandshakedone (node:_tls_wrap:856:12) { actual_server-1 | code: 'UNABLE_TO_GET_ISSUER_CERT_LOCALLY' actual_server-1 | } ``` I have a custom internal domain and I'm using Caddy as a reverse proxy. I've had similar issues with other selfhosted apps which were resolved by adding the custom certs to those containers. I've tried adding the following to a `Dockerfile`: ``` FROM docker.io/actualbudget/actual-server:latest COPY ca-certificates.crt /opt/ca-certificates.crt RUN apt-get update && apt-get install -y ca-certificates RUN update-ca-certificates ``` And I've also tried the `ca-certificates.ca` as a volume in the `docker-compose.yml` file: ``` ... - /opt/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt ... ``` I'm not too familiar with `node` so I'm probably adding the certs incorrectly? My authentik domain is `https://authentik.customdomain`
Author
Owner

@tr-io commented on GitHub (Jan 26, 2025):

Oh it was the path. I changed the COPY line to:

...
COPY ca-certificates.crt /usr/local/share/ca-certificates/
...

per the instructions here and it worked! My bad, was a user error!

@tr-io commented on GitHub (Jan 26, 2025): Oh it was the path. I changed the `COPY` line to: ``` ... COPY ca-certificates.crt /usr/local/share/ca-certificates/ ... ``` per [the instructions here](https://docs.docker.com/engine/network/ca-certs/#add-certificates-to-images) and it worked! My bad, was a user error!
Author
Owner

@sgloutnikov commented on GitHub (Jan 29, 2025):

Are we able to disable password auth on the login screen at the moment? I have OpenID working, and have disabled password login method via an ENV variable, but the password login option is still available in the dropdown.

My docker-compose.yaml:

environment:
      - ACTUAL_LOGIN_METHOD=openid
      - ACTUAL_ALLOWED_LOGIN_METHODS=openid
@sgloutnikov commented on GitHub (Jan 29, 2025): Are we able to disable password auth on the login screen at the moment? I have OpenID working, and have disabled password login method via an ENV variable, but the password login option is still available in the dropdown. My docker-compose.yaml: ```yaml environment: - ACTUAL_LOGIN_METHOD=openid - ACTUAL_ALLOWED_LOGIN_METHODS=openid ```
Author
Owner

@nicedevil007 commented on GitHub (Jan 29, 2025):

Are we able to disable password auth on the login screen at the moment? I have OpenID working, and have disabled password login method via an ENV variable, but the password login option is still available in the dropdown.

My docker-compose.yaml:

environment:
      - ACTUAL_LOGIN_METHOD=openid
      - ACTUAL_ALLOWED_LOGIN_METHODS=openid

Would be cool when this can be implemented.

@nicedevil007 commented on GitHub (Jan 29, 2025): > Are we able to disable password auth on the login screen at the moment? I have OpenID working, and have disabled password login method via an ENV variable, but the password login option is still available in the dropdown. > > My docker-compose.yaml: > > ```yaml > environment: > - ACTUAL_LOGIN_METHOD=openid > - ACTUAL_ALLOWED_LOGIN_METHODS=openid > ``` Would be cool when this can be implemented.
Author
Owner

@SplendidAppendix commented on GitHub (Jan 31, 2025):

Are we able to disable password auth on the login screen at the moment? I have OpenID working, and have disabled password login method via an ENV variable, but the password login option is still available in the dropdown.
My docker-compose.yaml:
environment:
- ACTUAL_LOGIN_METHOD=openid
- ACTUAL_ALLOWED_LOGIN_METHODS=openid

Would be cool when this can be implemented.

Came here to ask the same thing.

I'm trying to update the config to disable both Password login, and to make OpenID the only allowed login per the docs here, but still getting the dropdown. Because of that, I can't tell if the config is actually working for that or if it's just not implemented. Also, it would be helpful to have an option to bypass the login screen completely when using OpenID so it just goes straight to the identity provider.

@SplendidAppendix commented on GitHub (Jan 31, 2025): > > Are we able to disable password auth on the login screen at the moment? I have OpenID working, and have disabled password login method via an ENV variable, but the password login option is still available in the dropdown. > > My docker-compose.yaml: > > environment: > > - ACTUAL_LOGIN_METHOD=openid > > - ACTUAL_ALLOWED_LOGIN_METHODS=openid > > Would be cool when this can be implemented. Came here to ask the same thing. I'm trying to update the config to disable both Password login, and to make OpenID the only allowed login per the docs [here](https://actualbudget.org/docs/config/), but still getting the dropdown. Because of that, I can't tell if the config is actually working for that or if it's just not implemented. Also, it would be helpful to have an option to bypass the login screen completely when using OpenID so it just goes straight to the identity provider.
Author
Owner

@lelemm commented on GitHub (Feb 6, 2025):

based on this topic, I asked chatgpt to summarize what was discussed here:

Consolidated Feedback on OpenID and Multi-User Support for Actual Budget


General Overview

This discussion tracks feedback, bug reports, and improvement suggestions related to the OpenID and multi-user support feature in Actual Budget. Below is a consolidated summary of reported issues, solutions, and requested improvements.


1. Setup Issues & Troubleshooting

Common Errors Reported:

  1. "openid-grant-failed" due to missing iss in response

    • Occurred when trying to log in with Authelia and Authentik.
    • Solution: Ensure Authelia is correctly configured and, if necessary, switch authMethod to OAuth2 in config.json.
    • Running disable-openid and enable-openid commands was required to apply changes.
  2. Error: "unable to get local issuer certificate"

    • Issue when setting up OpenID with a self-hosted Authentik using Caddy as a reverse proxy.
    • Solution: Ensure certificates are copied correctly to /usr/local/share/ca-certificates/ and update CA certs accordingly.
  3. Error: "Invalid callback URL" when using Pocket ID

    • Solution: The correct callback URL format is https://actual.budget.tld/openid/callback.
  4. Users need to be manually created before logging in

    • OpenID does not automatically create user accounts in Actual.
    • Solution: Users need to be manually added via the User Directory.
  5. Switching Docker container from edge-alpine to edge

    • Required to include npm for running OpenID setup commands.
  6. Login works for the first user but fails for additional users

    • Signing in with a second user resulted in openid-grant-failed errors, and signing back in with the first user caused the same issue.
    • Solution: New users must be explicitly granted access via the User Directory.

2. User Experience (UX) & Documentation Improvements

Proposed UX Enhancements:

  1. Add a warning in the "Enable OpenID" dialog

    • Users should be reminded to export their data before enabling OpenID, not for technical reasons but to reduce support requests from users thinking their data was lost.
  2. Consider adding a guided data backup flow

    • A step-by-step process for backing up data before enabling experimental features could improve safety and ease of use.
  3. Clarify in the documentation that OpenID does not create users automatically

    • Users should be informed that they must manually add new accounts after enabling OpenID.
  4. Provide an option to bypass the login screen

    • When OpenID is the only login method, users should have the option to be redirected directly to the identity provider.

3. Feature Requests & Enhancements

Feature Requests:

  1. Support multi-user login without OpenID

    • Some users want multi-user support but without requiring OpenID.
  2. Fix SimpleFin token sharing issue

    • Bug: When multiple users/budgets exist, they share the same SimpleFin token, which results in unintended data access.
    • Expected Behavior: Each budget should have its own separate SimpleFin token.
  3. Ability to disable password login when OpenID is enabled

    • Setting environment variables (ACTUAL_LOGIN_METHOD=openid) does not remove password login from the dropdown.
    • Expected Behavior: If OpenID is the only allowed method, the password option should be hidden.
  4. Automatic user provisioning with OpenID

    • OpenID logins should automatically create user accounts in Actual instead of requiring manual creation.

4. User Experiences & Success Stories

Users Who Successfully Set Up OpenID

  • Pocket ID: Works correctly once the proper callback URL is set.
  • Authentik: Successfully configured OpenID login.
  • Self-hosted with Caddy: Works after fixing certificate paths.

Users Who Faced Challenges

  • Authelia users: Faced issues due to potential OAuth2 vs. OpenID incompatibility.
  • Authentik users: Faced issues with missing issuer certificate and manual user creation.

5. Summary of Next Steps

Fixes & Enhancements Required:

Clarify in documentation that OpenID does not auto-create users.
Fix SimpleFin token sharing issue for multi-user environments.
Allow disabling password login completely when OpenID is enforced.
Provide a direct redirect option when OpenID is the only method. https://github.com/actualbudget/actual/pull/4399
Improve OpenID user provisioning (automatic user creation on first login).
Improve UX with data backup prompts before enabling OpenID.


Final Thoughts

The OpenID and multi-user feature in Actual is highly appreciated but still requires refinements, particularly in automatic user creation, improved UX, and better support for multiple budgets.

@lelemm commented on GitHub (Feb 6, 2025): based on this topic, I asked chatgpt to summarize what was discussed here: ## **Consolidated Feedback on OpenID and Multi-User Support for Actual Budget** --- ## **General Overview** This discussion tracks feedback, bug reports, and improvement suggestions related to the **OpenID and multi-user support** feature in Actual Budget. Below is a consolidated summary of reported issues, solutions, and requested improvements. --- ## **1. Setup Issues & Troubleshooting** ### **Common Errors Reported:** 1. **"openid-grant-failed" due to missing `iss` in response** - Occurred when trying to log in with Authelia and Authentik. - **Solution:** Ensure Authelia is correctly configured and, if necessary, switch `authMethod` to **OAuth2** in `config.json`. - Running `disable-openid` and `enable-openid` commands was required to apply changes. 2. **Error: "unable to get local issuer certificate"** - Issue when setting up OpenID with a self-hosted Authentik using Caddy as a reverse proxy. - **Solution:** Ensure certificates are copied correctly to `/usr/local/share/ca-certificates/` and update CA certs accordingly. 3. **Error: "Invalid callback URL" when using Pocket ID** - **Solution:** The correct callback URL format is `https://actual.budget.tld/openid/callback`. 4. **Users need to be manually created before logging in** - OpenID does not automatically create user accounts in Actual. - **Solution:** Users need to be manually added via the User Directory. 5. **Switching Docker container from `edge-alpine` to `edge`** - Required to include `npm` for running OpenID setup commands. 6. **Login works for the first user but fails for additional users** - Signing in with a second user resulted in `openid-grant-failed` errors, and signing back in with the first user caused the same issue. - **Solution:** New users must be explicitly granted access via the **User Directory**. --- ## **2. User Experience (UX) & Documentation Improvements** ### **Proposed UX Enhancements:** 1. **Add a warning in the "Enable OpenID" dialog** - Users should be reminded to **export their data** before enabling OpenID, not for technical reasons but to **reduce support requests** from users thinking their data was lost. 2. **Consider adding a guided data backup flow** - A step-by-step process for backing up data before enabling experimental features could improve safety and ease of use. 3. **Clarify in the documentation that OpenID does not create users automatically** - Users should be informed that they must **manually add new accounts** after enabling OpenID. 4. **Provide an option to bypass the login screen** - When OpenID is the only login method, users should have the option to be redirected directly to the identity provider. --- ## **3. Feature Requests & Enhancements** ### **Feature Requests:** 1. **Support multi-user login without OpenID** - Some users want multi-user support but without requiring OpenID. 2. **Fix SimpleFin token sharing issue** - **Bug:** When multiple users/budgets exist, they **share the same SimpleFin token**, which results in unintended data access. - **Expected Behavior:** Each budget should have its own separate SimpleFin token. 3. **Ability to disable password login when OpenID is enabled** - Setting environment variables (`ACTUAL_LOGIN_METHOD=openid`) **does not remove password login** from the dropdown. - **Expected Behavior:** If OpenID is the only allowed method, the password option should be hidden. 4. **Automatic user provisioning with OpenID** - OpenID logins should automatically create user accounts in Actual instead of requiring manual creation. --- ## **4. User Experiences & Success Stories** ### **Users Who Successfully Set Up OpenID** - **Pocket ID:** Works correctly once the proper callback URL is set. - **Authentik:** Successfully configured OpenID login. - **Self-hosted with Caddy:** Works after fixing certificate paths. ### **Users Who Faced Challenges** - **Authelia users:** Faced issues due to potential **OAuth2 vs. OpenID incompatibility**. - **Authentik users:** Faced issues with **missing issuer certificate** and **manual user creation**. --- ## **5. Summary of Next Steps** ### **Fixes & Enhancements Required:** ⏳ **Clarify in documentation** that OpenID does not auto-create users. ⏳ **Fix SimpleFin token sharing issue** for multi-user environments. ⏳ **Allow disabling password login completely** when OpenID is enforced. ✔ **Provide a direct redirect option** when OpenID is the only method. https://github.com/actualbudget/actual/pull/4399 ⏳ **Improve OpenID user provisioning** (automatic user creation on first login). ⏳ **Improve UX with data backup prompts** before enabling OpenID. --- ### **Final Thoughts** The OpenID and multi-user feature in Actual is highly appreciated but still requires refinements, particularly in **automatic user creation, improved UX, and better support for multiple budgets**.
Author
Owner

@JazzyJosh commented on GitHub (Feb 7, 2025):

Is there a specific reason there's not an environment variable for auth type and it has to be set manually in the config?

Seems like it'll be a pain to set up Github/other OAuth2 mechanisms on hosts like fly.io and pika pods. Presumably you'd need to extend the released docker image to customize the config

I'd tinker with the change myself, but I don't have a ton of auth experience so don't want to mess around with that too much.

@JazzyJosh commented on GitHub (Feb 7, 2025): Is there a specific reason there's not an environment variable for auth type and it has to be set manually in the config? Seems like it'll be a pain to set up Github/other OAuth2 mechanisms on hosts like fly.io and pika pods. Presumably you'd need to extend the released docker image to customize the config I'd tinker with the change myself, but I don't have a ton of auth experience so don't want to mess around with that too much.
Author
Owner

@lelemm commented on GitHub (Feb 7, 2025):

Is there a specific reason there's not an environment variable for auth type and it has to be set manually in the config?

Seems like it'll be a pain to set up Github/other OAuth2 mechanisms on hosts like fly.io and pika pods. Presumably you'd need to extend the released docker image to customize the config

I'd tinker with the change myself, but I don't have a ton of auth experience so don't want to mess around with that too much.

I'm very busy at work lately. I will do changes on this when I'm more available.

@lelemm commented on GitHub (Feb 7, 2025): > Is there a specific reason there's not an environment variable for auth type and it has to be set manually in the config? > > Seems like it'll be a pain to set up Github/other OAuth2 mechanisms on hosts like fly.io and pika pods. Presumably you'd need to extend the released docker image to customize the config > > I'd tinker with the change myself, but I don't have a ton of auth experience so don't want to mess around with that too much. I'm very busy at work lately. I will do changes on this when I'm more available.
Author
Owner

@JazzyJosh commented on GitHub (Feb 8, 2025):

No rush of course, appreciate your contributions.

@JazzyJosh commented on GitHub (Feb 8, 2025): No rush of course, appreciate your contributions.
Author
Owner

@ishanjain28 commented on GitHub (Feb 9, 2025):

Hi @lelemm I would like to add a feature request here.

I do not expose actual budget's web interface to public for security reasons and it sits behind the Authelia Login page. I have configured open id and right now, I have to login twice to get to the AB dashboard.

Would you consider adding a flag to auto redirect user to the open id login page if open id is configured when the user opens the AB website ?

Auto redirect in combination with pre configured consent would mean that I can have a better login flow where people have to login just once to Authelia. After which, They'll come to AB login page which redirects them to the open id page. Then, We have pre configured consent so they are immediately sent back to AB with the login token.

This'll result in a better login flow without compromising on security in any way

@ishanjain28 commented on GitHub (Feb 9, 2025): Hi @lelemm I would like to add a feature request here. I do not expose actual budget's web interface to public for security reasons and it sits behind the Authelia Login page. I have configured open id and right now, I have to login twice to get to the AB dashboard. Would you consider adding a flag to auto redirect user to the open id login page if open id is configured when the user opens the AB website ? Auto redirect in combination with pre configured consent would mean that I can have a better login flow where people have to login just once to Authelia. After which, They'll come to AB login page which redirects them to the open id page. Then, We have pre configured consent so they are immediately sent back to AB with the login token. This'll result in a better login flow without compromising on security in any way
Author
Owner

@danielgraycode commented on GitHub (Feb 9, 2025):

This feature is working great, just one suggestion:
I run actual over several domains to provide convinient access methods for different persons, however with the openID functionality it is restricted to one callback URL, meaning it isn't compatible with my current setup. Is it possible to implement a list of allowed hostnames to redirect to/auto grab from the current URL to allow for multi domain functionality?

@danielgraycode commented on GitHub (Feb 9, 2025): This feature is working great, just one suggestion: I run actual over several domains to provide convinient access methods for different persons, however with the openID functionality it is restricted to one callback URL, meaning it isn't compatible with my current setup. Is it possible to implement a list of allowed hostnames to redirect to/auto grab from the current URL to allow for multi domain functionality?
Author
Owner

@pboling commented on GitHub (Feb 11, 2025):

I'd like to get some clarity on what type of OpenID this feature targets. Based on a tiny number of references in comments, and the release notes, it looks like OpenID Connect, which is based on the OAuth 2 standard. If that is the case, what is the difference between the openid and oauth2 settings? OpenID, when used without "Connect", tends to refer to the older OpenID v1 and OpenID v2 standards, which are now deprecated in favor of OpenID Connect (OIDC), which is OpenID v3 in spirit, but never referred to as such.

@pboling commented on GitHub (Feb 11, 2025): I'd like to get some clarity on what type of OpenID this feature targets. Based on a tiny number of references in comments, and the release notes, it looks like OpenID Connect, which is based on the OAuth 2 standard. If that is the case, what is the difference between the `openid` and `oauth2` settings? OpenID, when used without "Connect", tends to refer to the older OpenID v1 and OpenID v2 standards, which are now deprecated in favor of OpenID Connect (OIDC), which is OpenID v3 in spirit, but never referred to as such.
Author
Owner

@lelemm commented on GitHub (Feb 11, 2025):

this is for OIDC, it serves as authentication and identity.
the oauth2 is just for backward compatibility, when there is no identity endpoint, so you can specify other endpoint to search for identity (like github https://api.github.com/user )

@lelemm commented on GitHub (Feb 11, 2025): this is for OIDC, it serves as authentication and identity. the oauth2 is just for backward compatibility, when there is no identity endpoint, so you can specify other endpoint to search for identity (like github https://api.github.com/user )
Author
Owner

@jantznick commented on GitHub (Feb 14, 2025):

I'm running into some issues where when I go to the user directory page and it makes a get call to get the user list, it's giving me a 'Too many requests, please try again later' error. This is then preventing me from creating a new user as well when it tries to make the new user post. Sometimes it seems to log me out too. It seems to be hitting the server over and over making the get user list request, interestingly, after a little bit of this the requests start to run just fine, but the POST to create the new user is still broke.

Running in docker on linux and accessing on a mac. Only local network, use authentik as the provider. I'm happy to help troubleshoot with any more info that might be needed. I will try and get a video of it happening in the next day or so.

Otherwise, very appreciative of everyone working on this feature.

Edit to add, it's definitely hammering the server with the get users request, over 2000 of them while I wrote up that comment, was able to copy the POST to create a user as curl from the network tab and sent it from the hosting server and it worked just fine to create the new user.

@jantznick commented on GitHub (Feb 14, 2025): I'm running into some issues where when I go to the user directory page and it makes a get call to get the user list, it's giving me a 'Too many requests, please try again later' error. This is then preventing me from creating a new user as well when it tries to make the new user post. Sometimes it seems to log me out too. It seems to be hitting the server over and over making the get user list request, interestingly, after a little bit of this the requests start to run just fine, but the POST to create the new user is still broke. Running in docker on linux and accessing on a mac. Only local network, use authentik as the provider. I'm happy to help troubleshoot with any more info that might be needed. I will try and get a video of it happening in the next day or so. Otherwise, very appreciative of everyone working on this feature. Edit to add, it's definitely hammering the server with the get users request, over 2000 of them while I wrote up that comment, was able to copy the POST to create a user as curl from the network tab and sent it from the hosting server and it worked just fine to create the new user.
Author
Owner

@lelemm commented on GitHub (Feb 14, 2025):

I'm running into some issues where when I go to the user directory page and it makes a get call to get the user list, it's giving me a 'Too many requests, please try again later' error. This is then preventing me from creating a new user as well when it tries to make the new user post. Sometimes it seems to log me out too. It seems to be hitting the server over and over making the get user list request, interestingly, after a little bit of this the requests start to run just fine, but the POST to create the new user is still broke.

Running in docker on linux and accessing on a mac. Only local network, use authentik as the provider. I'm happy to help troubleshoot with any more info that might be needed. I will try and get a video of it happening in the next day or so.

Otherwise, very appreciative of everyone working on this feature.

Edit to add, it's definitely hammering the server with the get users request, over 2000 of them while I wrote up that comment, was able to copy the POST to create a user as curl from the network tab and sent it from the hosting server and it worked just fine to create the new user.

I noticed that too. I'm investigating

@lelemm commented on GitHub (Feb 14, 2025): > I'm running into some issues where when I go to the user directory page and it makes a get call to get the user list, it's giving me a 'Too many requests, please try again later' error. This is then preventing me from creating a new user as well when it tries to make the new user post. Sometimes it seems to log me out too. It seems to be hitting the server over and over making the get user list request, interestingly, after a little bit of this the requests start to run just fine, but the POST to create the new user is still broke. > > Running in docker on linux and accessing on a mac. Only local network, use authentik as the provider. I'm happy to help troubleshoot with any more info that might be needed. I will try and get a video of it happening in the next day or so. > > Otherwise, very appreciative of everyone working on this feature. > > Edit to add, it's definitely hammering the server with the get users request, over 2000 of them while I wrote up that comment, was able to copy the POST to create a user as curl from the network tab and sent it from the hosting server and it worked just fine to create the new user. I noticed that too. I'm investigating
Author
Owner

@SplendidAppendix commented on GitHub (Feb 14, 2025):

Hi @lelemm I would like to add a feature request here.

I do not expose actual budget's web interface to public for security reasons and it sits behind the Authelia Login page. I have configured open id and right now, I have to login twice to get to the AB dashboard.

Would you consider adding a flag to auto redirect user to the open id login page if open id is configured when the user opens the AB website ?

Auto redirect in combination with pre configured consent would mean that I can have a better login flow where people have to login just once to Authelia. After which, They'll come to AB login page which redirects them to the open id page. Then, We have pre configured consent so they are immediately sent back to AB with the login token.

This'll result in a better login flow without compromising on security in any way

Tell me you haven't read the discussion without telling me you haven't read the discussion 😛. Auto redirect to the IDP has already been called out.

@SplendidAppendix commented on GitHub (Feb 14, 2025): > Hi [@lelemm](https://github.com/lelemm) I would like to add a feature request here. > > I do not expose actual budget's web interface to public for security reasons and it sits behind the Authelia Login page. I have configured open id and right now, I have to login twice to get to the AB dashboard. > > Would you consider adding a flag to auto redirect user to the open id login page if open id is configured when the user opens the AB website ? > > Auto redirect in combination with pre configured consent would mean that I can have a better login flow where people have to login just once to Authelia. After which, They'll come to AB login page which redirects them to the open id page. Then, We have pre configured consent so they are immediately sent back to AB with the login token. > > This'll result in a better login flow without compromising on security in any way Tell me you haven't read the discussion without telling me you haven't read the discussion 😛. Auto redirect to the IDP has already been called out.
Author
Owner

@ishanjain28 commented on GitHub (Feb 14, 2025):

Ah okay. I did read it but I must have missed it. Thanks for the correction

@ishanjain28 commented on GitHub (Feb 14, 2025): Ah okay. I did read it but I must have missed it. Thanks for the correction
Author
Owner

@lelemm commented on GitHub (Feb 15, 2025):

Auto redirect is already developed for my branch, I just need to implement the OIDC Provider logout to avoid login again after a logout

@lelemm commented on GitHub (Feb 15, 2025): Auto redirect is already developed for my branch, I just need to implement the OIDC Provider logout to avoid login again after a logout
Author
Owner

@pboling commented on GitHub (Feb 15, 2025):

@lelemm Wondering if there has been any thought to separating the data synced back to local devices from the server when multi-user is enabled.

If a single server is used to host budgets of multiple people who have no connection to each other it seems like all their data would sync to all of their individual devices. Is that how it works? Is there any documentation or link to a discussion about how this works from a security and privacy perspective?

With ElectricSQL (Sqlite in browser and PostgreSQL on Server) it uses DDLX rules and Shapes to control what each device receives from the cloud (I.e. from potential other users).

ref: https://legacy.electric-sql.com/docs/intro/sync-controls

@pboling commented on GitHub (Feb 15, 2025): @lelemm Wondering if there has been any thought to separating the data synced back to local devices from the server when multi-user is enabled. If a single server is used to host budgets of multiple people who have no connection to each other it seems like all their data would sync to all of their individual devices. Is that how it works? Is there any documentation or link to a discussion about how this works from a security and privacy perspective? With ElectricSQL (Sqlite in browser and PostgreSQL on Server) it uses DDLX rules and Shapes to control what each device receives from the cloud (I.e. from potential other users). ref: https://legacy.electric-sql.com/docs/intro/sync-controls
Author
Owner

@lelemm commented on GitHub (Feb 18, 2025):

5. Summary of Next Steps

Fixes & Enhancements Required:

Clarify in documentation that OpenID does not auto-create users.
Fix SimpleFin token sharing issue for multi-user environments.
Allow disabling password login completely when OpenID is enforced.
Provide a direct redirect option when OpenID is the only method. https://github.com/actualbudget/actual/pull/4399
Improve OpenID user provisioning (automatic user creation on first login).
Improve UX with data backup prompts before enabling OpenID.

@lelemm commented on GitHub (Feb 18, 2025): ## **5. Summary of Next Steps** ### **Fixes & Enhancements Required:** ⏳ **Clarify in documentation** that OpenID does not auto-create users. ⏳ **Fix SimpleFin token sharing issue** for multi-user environments. ⏳ **Allow disabling password login completely** when OpenID is enforced. ✔ **Provide a direct redirect option** when OpenID is the only method. https://github.com/actualbudget/actual/pull/4399 ⏳ **Improve OpenID user provisioning** (automatic user creation on first login). ⏳ **Improve UX with data backup prompts** before enabling OpenID.
Author
Owner

@SplendidAppendix commented on GitHub (Feb 18, 2025):

Ah okay. I did read it but I must have missed it. Thanks for the correction

I was just teasing, hope it didn't come off as anything else. I just wanted to make sure you saw that it was already in the works at the time.

@SplendidAppendix commented on GitHub (Feb 18, 2025): > Ah okay. I did read it but I must have missed it. Thanks for the correction I was just teasing, hope it didn't come off as anything else. I just wanted to make sure you saw that it was already in the works at the time.
Author
Owner

@lelemm commented on GitHub (Feb 20, 2025):

5. Summary of Next Steps

Fixes & Enhancements Required:

Enhance docs with the many OpenID changes.
Fix SimpleFin token sharing issue for multi-user environments.
✔️ Allow disabling password login completely when OpenID is enforced. https://github.com/actualbudget/actual/pull/4423
Provide a direct redirect option when OpenID is the only method. https://github.com/actualbudget/actual/pull/4399
✔️ Improve OpenID user provisioning (automatic user creation on first login). https://github.com/actualbudget/actual/pull/4421
Improve UX with data backup prompts before enabling OpenID.

@lelemm commented on GitHub (Feb 20, 2025): ## **5. Summary of Next Steps** ### **Fixes & Enhancements Required:** ⏳ **Enhance docs** with the many OpenID changes. ⏳ **Fix SimpleFin token sharing issue** for multi-user environments. ✔️ **Allow disabling password login completely** when OpenID is enforced. https://github.com/actualbudget/actual/pull/4423 ✅ **Provide a direct redirect option** when OpenID is the only method. https://github.com/actualbudget/actual/pull/4399 ✔️ **Improve OpenID user provisioning** (automatic user creation on first login). https://github.com/actualbudget/actual/pull/4421 ⏳ **Improve UX with data backup prompts** before enabling OpenID.
Author
Owner

@rcrisanti commented on GitHub (Feb 21, 2025):

I'm running into some issues where when I go to the user directory page and it makes a get call to get the user list, it's giving me a 'Too many requests, please try again later' error. This is then preventing me from creating a new user as well when it tries to make the new user post. Sometimes it seems to log me out too. It seems to be hitting the server over and over making the get user list request, interestingly, after a little bit of this the requests start to run just fine, but the POST to create the new user is still broke.
Running in docker on linux and accessing on a mac. Only local network, use authentik as the provider. I'm happy to help troubleshoot with any more info that might be needed. I will try and get a video of it happening in the next day or so.
Otherwise, very appreciative of everyone working on this feature.
Edit to add, it's definitely hammering the server with the get users request, over 2000 of them while I wrote up that comment, was able to copy the POST to create a user as curl from the network tab and sent it from the hosting server and it worked just fine to create the new user.

I noticed that too. I'm investigating

I also am running into this exact issue. Just want to make sure I'm not missing anything, is there a diagnosis/solution to this?

@rcrisanti commented on GitHub (Feb 21, 2025): > > I'm running into some issues where when I go to the user directory page and it makes a get call to get the user list, it's giving me a 'Too many requests, please try again later' error. This is then preventing me from creating a new user as well when it tries to make the new user post. Sometimes it seems to log me out too. It seems to be hitting the server over and over making the get user list request, interestingly, after a little bit of this the requests start to run just fine, but the POST to create the new user is still broke. > > Running in docker on linux and accessing on a mac. Only local network, use authentik as the provider. I'm happy to help troubleshoot with any more info that might be needed. I will try and get a video of it happening in the next day or so. > > Otherwise, very appreciative of everyone working on this feature. > > Edit to add, it's definitely hammering the server with the get users request, over 2000 of them while I wrote up that comment, was able to copy the POST to create a user as curl from the network tab and sent it from the hosting server and it worked just fine to create the new user. > > I noticed that too. I'm investigating I also am running into this exact issue. Just want to make sure I'm not missing anything, is there a diagnosis/solution to this?
Author
Owner

@lelemm commented on GitHub (Feb 21, 2025):

I'm running into some issues where when I go to the user directory page and it makes a get call to get the user list, it's giving me a 'Too many requests, please try again later' error. This is then preventing me from creating a new user as well when it tries to make the new user post. Sometimes it seems to log me out too. It seems to be hitting the server over and over making the get user list request, interestingly, after a little bit of this the requests start to run just fine, but the POST to create the new user is still broke.
Running in docker on linux and accessing on a mac. Only local network, use authentik as the provider. I'm happy to help troubleshoot with any more info that might be needed. I will try and get a video of it happening in the next day or so.
Otherwise, very appreciative of everyone working on this feature.
Edit to add, it's definitely hammering the server with the get users request, over 2000 of them while I wrote up that comment, was able to copy the POST to create a user as curl from the network tab and sent it from the hosting server and it worked just fine to create the new user.

I noticed that too. I'm investigating

I also am running into this exact issue. Just want to make sure I'm not missing anything, is there a diagnosis/solution to this?

There is a fix for this on next release

@lelemm commented on GitHub (Feb 21, 2025): > > > I'm running into some issues where when I go to the user directory page and it makes a get call to get the user list, it's giving me a 'Too many requests, please try again later' error. This is then preventing me from creating a new user as well when it tries to make the new user post. Sometimes it seems to log me out too. It seems to be hitting the server over and over making the get user list request, interestingly, after a little bit of this the requests start to run just fine, but the POST to create the new user is still broke. > > > Running in docker on linux and accessing on a mac. Only local network, use authentik as the provider. I'm happy to help troubleshoot with any more info that might be needed. I will try and get a video of it happening in the next day or so. > > > Otherwise, very appreciative of everyone working on this feature. > > > Edit to add, it's definitely hammering the server with the get users request, over 2000 of them while I wrote up that comment, was able to copy the POST to create a user as curl from the network tab and sent it from the hosting server and it worked just fine to create the new user. > > > > > > I noticed that too. I'm investigating > > I also am running into this exact issue. Just want to make sure I'm not missing anything, is there a diagnosis/solution to this? There is a fix for this on next release
Author
Owner

@cswrd commented on GitHub (Feb 23, 2025):

Are there any plans to be able to migrate or merge existing actual budget instances into one with multi-user support?

@cswrd commented on GitHub (Feb 23, 2025): Are there any plans to be able to migrate or merge existing actual budget instances into one with multi-user support?
Author
Owner

@tugdualenligne commented on GitHub (Feb 23, 2025):

Not sure I get it: aren’t existing instances natively Multi-user? I just
upgraded the container to the latest version and that’s it

@tugdualenligne commented on GitHub (Feb 23, 2025): Not sure I get it: aren’t existing instances natively Multi-user? I just upgraded the container to the latest version and that’s it
Author
Owner

@cswrd commented on GitHub (Feb 23, 2025):

I mean multiple separate instances that were create before there was an (experimental) multi-user support, e.g. when hosting separate instances for family members. So will it be possible to migrate / merge them into one instance facilitating the integrated multi-user feature.

@cswrd commented on GitHub (Feb 23, 2025): I mean multiple separate instances that were create before there was an (experimental) multi-user support, e.g. when hosting separate instances for family members. So will it be possible to migrate / merge them into one instance facilitating the integrated multi-user feature.
Author
Owner

@lelemm commented on GitHub (Feb 23, 2025):

Just export the budget and import in the final instance

@lelemm commented on GitHub (Feb 23, 2025): Just export the budget and import in the final instance
Author
Owner

@sebastianfredette commented on GitHub (Feb 23, 2025):

Heyo, first -- thank you for doing this!

Second, I might be doing something wrong (or hopping on this before it's ready), but I'm having a bit of trouble with the new ACTUAL_OPENID_ENFORCE=true environmental variable (added by #4423 ). Adding it to my compose.yml seems to have the intented effect (i.e., only the OpenID button is available when navigating to my Actual instance). Clicking "Sign in with OpenID" also directs me to my SSO provider as expected. But, if I hit the back button on my SSO page (before signing in), Actual offers to let me sign in with my password.

This might be intentional (in case SSO is misconfigured maybe?) but, if so, "enforce" might be a bit misleading.

@sebastianfredette commented on GitHub (Feb 23, 2025): Heyo, first -- thank you for doing this! Second, I might be doing something wrong (or hopping on this before it's ready), but I'm having a bit of trouble with the new `ACTUAL_OPENID_ENFORCE=true` environmental variable (added by #4423 ). Adding it to my `compose.yml` seems to have the intented effect (i.e., only the OpenID button is available when navigating to my Actual instance). Clicking "Sign in with OpenID" also directs me to my SSO provider as expected. _But_, if I hit the back button on my SSO page (before signing in), Actual offers to let me sign in with my password. This might be intentional (in case SSO is misconfigured maybe?) but, if so, "enforce" might be a bit misleading.
Author
Owner

@g4m3r7ag commented on GitHub (Feb 24, 2025):

Is there a way to disable the login with password option after OIDC is configured? I setup the app/provider in Authentik, setup OIDC in Actual using the UI, it took me back to the login and I chose login with OpenID and it authenticated me through Authentik correctly and seems to be working fine. But if I logout, the login screen gives me the option to login with either Open ID or Password. I was hoping to disable the password option from the login screen before exposing my Actual URL so that I can make transaction entries while out from my phone.

@g4m3r7ag commented on GitHub (Feb 24, 2025): Is there a way to disable the login with password option after OIDC is configured? I setup the app/provider in Authentik, setup OIDC in Actual using the UI, it took me back to the login and I chose login with OpenID and it authenticated me through Authentik correctly and seems to be working fine. But if I logout, the login screen gives me the option to login with either Open ID or Password. I was hoping to disable the password option from the login screen before exposing my Actual URL so that I can make transaction entries while out from my phone.
Author
Owner

@lelemm commented on GitHub (Feb 24, 2025):

Heyo, first -- thank you for doing this!

Second, I might be doing something wrong (or hopping on this before it's ready), but I'm having a bit of trouble with the new ACTUAL_OPENID_ENFORCE=true environmental variable (added by #4423 ). Adding it to my compose.yml seems to have the intented effect (i.e., only the OpenID button is available when navigating to my Actual instance). Clicking "Sign in with OpenID" also directs me to my SSO provider as expected. But, if I hit the back button on my SSO page (before signing in), Actual offers to let me sign in with my password.

This might be intentional (in case SSO is misconfigured maybe?) but, if so, "enforce" might be a bit misleading.

its not intentional. probably not triggering the filter when you hit back

@lelemm commented on GitHub (Feb 24, 2025): > Heyo, first -- thank you for doing this! > > Second, I might be doing something wrong (or hopping on this before it's ready), but I'm having a bit of trouble with the new `ACTUAL_OPENID_ENFORCE=true` environmental variable (added by [#4423](https://github.com/actualbudget/actual/pull/4423) ). Adding it to my `compose.yml` seems to have the intented effect (i.e., only the OpenID button is available when navigating to my Actual instance). Clicking "Sign in with OpenID" also directs me to my SSO provider as expected. _But_, if I hit the back button on my SSO page (before signing in), Actual offers to let me sign in with my password. > > This might be intentional (in case SSO is misconfigured maybe?) but, if so, "enforce" might be a bit misleading. its not intentional. probably not triggering the filter when you hit back
Author
Owner

@lelemm commented on GitHub (Feb 24, 2025):

Is there a way to disable the login with password option after OIDC is configured? I setup the app/provider in Authentik, setup OIDC in Actual using the UI, it took me back to the login and I chose login with OpenID and it authenticated me through Authentik correctly and seems to be working fine. But if I logout, the login screen gives me the option to login with either Open ID or Password. I was hoping to disable the password option from the login screen before exposing my Actual URL so that I can make transaction entries while out from my phone.

its being added next release: https://github.com/actualbudget/actual/pull/4423

@lelemm commented on GitHub (Feb 24, 2025): > Is there a way to disable the login with password option after OIDC is configured? I setup the app/provider in Authentik, setup OIDC in Actual using the UI, it took me back to the login and I chose login with OpenID and it authenticated me through Authentik correctly and seems to be working fine. But if I logout, the login screen gives me the option to login with either Open ID or Password. I was hoping to disable the password option from the login screen before exposing my Actual URL so that I can make transaction entries while out from my phone. its being added next release: https://github.com/actualbudget/actual/pull/4423
Author
Owner

@savely-krasovsky commented on GitHub (Feb 27, 2025):

At "User Directory" page something crazy is going on, it's trying to fetch /api/users forever until it starts to get 429:

Screenshot

Image

I use the latest v25.2.1, it's behind Traefik, anything special.

UPD. My guess problem is related to Traefik: https://community.traefik.io/t/http-router-removes-upstream-content-type-under-specific-conditions/25539

@savely-krasovsky commented on GitHub (Feb 27, 2025): At "User Directory" page something crazy is going on, it's trying to fetch `/api/users` forever until it starts to get 429: <details><summary>Screenshot</summary> <p> ![Image](https://github.com/user-attachments/assets/a47943a8-0882-43a0-bfad-6a1ab62c140a) </p> </details> I use the latest `v25.2.1`, it's behind Traefik, anything special. UPD. My guess problem is related to Traefik: https://community.traefik.io/t/http-router-removes-upstream-content-type-under-specific-conditions/25539
Author
Owner

@lelemm commented on GitHub (Feb 27, 2025):

At "User Directory" page something crazy is going on, it's trying to fetch /api/users forever until it starts to get 429: Image

I use the latest v25.2.1, it's behind Traefik, anything special.

UPD. My guess problem is related to Traefik: https://community.traefik.io/t/http-router-removes-upstream-content-type-under-specific-conditions/25539

There is a bug fix ready for next release

@lelemm commented on GitHub (Feb 27, 2025): > At "User Directory" page something crazy is going on, it's trying to fetch `/api/users` forever until it starts to get 429: ![Image](https://github.com/user-attachments/assets/a47943a8-0882-43a0-bfad-6a1ab62c140a) > > I use the latest `v25.2.1`, it's behind Traefik, anything special. > > UPD. My guess problem is related to Traefik: https://community.traefik.io/t/http-router-removes-upstream-content-type-under-specific-conditions/25539 There is a bug fix ready for next release
Author
Owner

@Fgdou commented on GitHub (Mar 1, 2025):

EDIT : fixed, I had a DNS issue with this container, not able to contact my local DNS

Hi,
I'm having issues when trying to configure oidc in actual settings for authentik :

An internal error occurred, sorry! Visit https://actualbudget.org/contact/ for support. (ref: internal)
actual_server-1  | Error setting up OpenID client: RPError: outgoing request timed out after 3500ms
actual_server-1  |     at /app/node_modules/openid-client/lib/helpers/request.js:140:13
actual_server-1  |     at async Issuer.discover (/app/node_modules/openid-client/lib/issuer.js:144:22)
actual_server-1  |     at async setupOpenIdClient (file:///app/src/accounts/openid.js:54:9)
actual_server-1  |     at async bootstrapOpenId (file:///app/src/accounts/openid.js:27:5)
actual_server-1  |     at async enableOpenID (file:///app/src/account-db.js:142:22)
actual_server-1  |     at async file:///app/src/app-openid.js:31:22
actual_server-1  | 2025-03-01T18:28:29.132Z info: POST 500 /openid/enable

My authentik is working fine for any other app

Here is my docker compose :

services:
  actual_server:
    image: docker.io/actualbudget/actual-server:25.3.0
    volumes:
      - /data/actual_budget:/data
    restart: unless-stopped
    networks:
      - nas
    labels:
      - 'traefik.enable=true'
      - 'traefik.http.routers.actual.rule=Host(`actual.xxx.xxx`)'
      - 'traefik.http.routers.actual.entryPoints=websecure'
      - 'traefik.http.services.actual.loadbalancer.server.port=5006'
  authentik:
    image: ghcr.io/goauthentik/server:2024.12.3
    restart: unless-stopped
    command: server
    container_name: authentik_server
    hostname: authentik_server
    networks:
      - nas
      - authentik
    labels:
      - 'traefik.enable=true'
      - 'traefik.http.routers.authentik.rule=Host(`auth.xxx.xxx`)'
      - 'traefik.http.routers.authentik.entryPoints=websecure'
      - 'traefik.http.services.authentik.loadbalancer.server.port=9000'
      - 'traefik.http.middlewares.authentik.forwardauth.address=http://authentik_server:9000/outpost.goauthentik.io/auth/traefik'
      - 'traefik.http.middlewares.authentik.forwardauth.trustForwardHeader=true'
      - 'traefik.http.middlewares.authentik.forwardauth.authResponseHeaders=X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid,X-authentik-jwt,X-authentik-meta-jwks,X-authentik-meta-outpost,X-authentik-meta-provider,X-authentik-meta-app,X-authentik-meta-version'


networks:
  nas:
@Fgdou commented on GitHub (Mar 1, 2025): EDIT : fixed, I had a DNS issue with this container, not able to contact my local DNS Hi, I'm having issues when trying to configure oidc in actual settings for authentik : ``` An internal error occurred, sorry! Visit https://actualbudget.org/contact/ for support. (ref: internal) ``` ``` actual_server-1 | Error setting up OpenID client: RPError: outgoing request timed out after 3500ms actual_server-1 | at /app/node_modules/openid-client/lib/helpers/request.js:140:13 actual_server-1 | at async Issuer.discover (/app/node_modules/openid-client/lib/issuer.js:144:22) actual_server-1 | at async setupOpenIdClient (file:///app/src/accounts/openid.js:54:9) actual_server-1 | at async bootstrapOpenId (file:///app/src/accounts/openid.js:27:5) actual_server-1 | at async enableOpenID (file:///app/src/account-db.js:142:22) actual_server-1 | at async file:///app/src/app-openid.js:31:22 actual_server-1 | 2025-03-01T18:28:29.132Z info: POST 500 /openid/enable ``` My authentik is working fine for any other app Here is my docker compose : ```yaml services: actual_server: image: docker.io/actualbudget/actual-server:25.3.0 volumes: - /data/actual_budget:/data restart: unless-stopped networks: - nas labels: - 'traefik.enable=true' - 'traefik.http.routers.actual.rule=Host(`actual.xxx.xxx`)' - 'traefik.http.routers.actual.entryPoints=websecure' - 'traefik.http.services.actual.loadbalancer.server.port=5006' authentik: image: ghcr.io/goauthentik/server:2024.12.3 restart: unless-stopped command: server container_name: authentik_server hostname: authentik_server networks: - nas - authentik labels: - 'traefik.enable=true' - 'traefik.http.routers.authentik.rule=Host(`auth.xxx.xxx`)' - 'traefik.http.routers.authentik.entryPoints=websecure' - 'traefik.http.services.authentik.loadbalancer.server.port=9000' - 'traefik.http.middlewares.authentik.forwardauth.address=http://authentik_server:9000/outpost.goauthentik.io/auth/traefik' - 'traefik.http.middlewares.authentik.forwardauth.trustForwardHeader=true' - 'traefik.http.middlewares.authentik.forwardauth.authResponseHeaders=X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid,X-authentik-jwt,X-authentik-meta-jwks,X-authentik-meta-outpost,X-authentik-meta-provider,X-authentik-meta-app,X-authentik-meta-version' networks: nas: ```
Author
Owner

@yieldhog commented on GitHub (Mar 2, 2025):

I'm having an issue with Authelia

App: v25.3.0 | Server: v25.3.0

I use the config.json to config as follows:

{ "openId": { "issuer": "https://auth.mydomain.com", "client_id": "actual-budget", "client_secret": "mysecret", "server_hostname": "https://budget.mydomain.com", "authMethod": "oauth2" } }

Authelia is setup exactly per the documentation here:

When I connect through OIDC, I get this error every time: {"status":"error","reason":"openid-grant-failed"} in the browser

Logs:
`GET 400 /openid/callback?code=authelia_ac_ejEmI7FqKWWG2jYY4Kzagu2niepX95dFvDg13RRzGqA.oSRafP55gQnVs50adrhWS8X-I0BxqKJeVGgdkCECXr8&iss=https%3A%2F%2Fauth.mydomain.com&scope=openid+email+profile&state=9Ld_FtiRpuUpnAAdO26nnJnMRovPhWEIj7MPkgh3UPI

'authelia_ac_ejEmI7FqKWWG2jYY4Kzagu2niepX95dFvDg13RRzGqA.oSRafP55gQnVs50adrhWS8X-I0BxqKJeVGgdkCECXr8',
params: {
at async file:///app/src/app-openid.js:87:26 {
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at loginWithOpenIdFinalize (file:///app/src/accounts/openid.js:178:31)
at Client.callback (/app/node_modules/openid-client/lib/client.js:463:13)
OpenID grant failed: RPError: iss missing from the response`

@yieldhog commented on GitHub (Mar 2, 2025): I'm having an issue with Authelia App: v25.3.0 | Server: v25.3.0 I use the config.json to config as follows: `{ "openId": { "issuer": "https://auth.mydomain.com", "client_id": "actual-budget", "client_secret": "mysecret", "server_hostname": "https://budget.mydomain.com", "authMethod": "oauth2" } }` Authelia is setup exactly per the documentation here: When I connect through OIDC, I get this error every time: {"status":"error","reason":"openid-grant-failed"} in the browser Logs: `GET 400 /openid/callback?code=authelia_ac_ejEmI7FqKWWG2jYY4Kzagu2niepX95dFvDg13RRzGqA.oSRafP55gQnVs50adrhWS8X-I0BxqKJeVGgdkCECXr8&iss=https%3A%2F%2Fauth.mydomain.com&scope=openid+email+profile&state=9Ld_FtiRpuUpnAAdO26nnJnMRovPhWEIj7MPkgh3UPI 'authelia_ac_ejEmI7FqKWWG2jYY4Kzagu2niepX95dFvDg13RRzGqA.oSRafP55gQnVs50adrhWS8X-I0BxqKJeVGgdkCECXr8', params: { at async file:///app/src/app-openid.js:87:26 { at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at loginWithOpenIdFinalize (file:///app/src/accounts/openid.js:178:31) at Client.callback (/app/node_modules/openid-client/lib/client.js:463:13) OpenID grant failed: RPError: iss missing from the response`
Author
Owner

@yieldhog commented on GitHub (Mar 2, 2025):

I'm having an issue with Authelia

App: v25.3.0 | Server: v25.3.0

I use the config.json to config as follows:

{ "openId": { "issuer": "https://auth.mydomain.com", "client_id": "actual-budget", "client_secret": "mysecret", "server_hostname": "https://budget.mydomain.com", "authMethod": "oauth2" } }

Authelia is setup exactly per the documentation here:

When I connect through OIDC, I get this error every time: {"status":"error","reason":"openid-grant-failed"} in the browser

Logs: `GET 400 /openid/callback?code=authelia_ac_ejEmI7FqKWWG2jYY4Kzagu2niepX95dFvDg13RRzGqA.oSRafP55gQnVs50adrhWS8X-I0BxqKJeVGgdkCECXr8&iss=https%3A%2F%2Fauth.mydomain.com&scope=openid+email+profile&state=9Ld_FtiRpuUpnAAdO26nnJnMRovPhWEIj7MPkgh3UPI

'authelia_ac_ejEmI7FqKWWG2jYY4Kzagu2niepX95dFvDg13RRzGqA.oSRafP55gQnVs50adrhWS8X-I0BxqKJeVGgdkCECXr8'�[39m, params: { at async �[90mfile:///app/�[39msrc/app-openid.js:87:26 { at process.processTicksAndRejections (node:internal/process/task_queues:95:5)�[39m at loginWithOpenIdFinalize �[90m(file:///app/�[39msrc/accounts/openid.js:178:31�[90m)�[39m at Client.callback �[90m(/app/�[39mnode_modules/�[4mopenid-client�[24m/lib/client.js:463:13�[90m)�[39m OpenID grant failed: RPError: iss missing from the response`

It appears I was able to fix this by loading config.json using the following response, perhaps it would make sense to update documentation at least for those of us using Authelia. https://github.com/actualbudget/actual/issues/4029#issuecomment-2561272700

@yieldhog commented on GitHub (Mar 2, 2025): > I'm having an issue with Authelia > > App: v25.3.0 | Server: v25.3.0 > > I use the config.json to config as follows: > > `{ "openId": { "issuer": "https://auth.mydomain.com", "client_id": "actual-budget", "client_secret": "mysecret", "server_hostname": "https://budget.mydomain.com", "authMethod": "oauth2" } }` > > Authelia is setup exactly per the documentation here: > > When I connect through OIDC, I get this error every time: {"status":"error","reason":"openid-grant-failed"} in the browser > > Logs: `GET 400 /openid/callback?code=authelia_ac_ejEmI7FqKWWG2jYY4Kzagu2niepX95dFvDg13RRzGqA.oSRafP55gQnVs50adrhWS8X-I0BxqKJeVGgdkCECXr8&iss=https%3A%2F%2Fauth.mydomain.com&scope=openid+email+profile&state=9Ld_FtiRpuUpnAAdO26nnJnMRovPhWEIj7MPkgh3UPI > > 'authelia_ac_ejEmI7FqKWWG2jYY4Kzagu2niepX95dFvDg13RRzGqA.oSRafP55gQnVs50adrhWS8X-I0BxqKJeVGgdkCECXr8'�[39m, params: { at async �[90mfile:///app/�[39msrc/app-openid.js:87:26 { at process.processTicksAndRejections (node:internal/process/task_queues:95:5)�[39m at loginWithOpenIdFinalize �[90m(file:///app/�[39msrc/accounts/openid.js:178:31�[90m)�[39m at Client.callback �[90m(/app/�[39mnode_modules/�[4mopenid-client�[24m/lib/client.js:463:13�[90m)�[39m OpenID grant failed: RPError: iss missing from the response` It appears I was able to fix this by loading config.json using the following response, perhaps it would make sense to update documentation at least for those of us using Authelia. https://github.com/actualbudget/actual/issues/4029#issuecomment-2561272700
Author
Owner

@lelemm commented on GitHub (Mar 3, 2025):

I'm having an issue with Authelia
App: v25.3.0 | Server: v25.3.0
I use the config.json to config as follows:
{ "openId": { "issuer": "https://auth.mydomain.com", "client_id": "actual-budget", "client_secret": "mysecret", "server_hostname": "https://budget.mydomain.com", "authMethod": "oauth2" } }
Authelia is setup exactly per the documentation here:
When I connect through OIDC, I get this error every time: {"status":"error","reason":"openid-grant-failed"} in the browser
Logs: GET 400 /openid/callback?code=authelia_ac_ejEmI7FqKWWG2jYY4Kzagu2niepX95dFvDg13RRzGqA.oSRafP55gQnVs50adrhWS8X-I0BxqKJeVGgdkCECXr8&iss=https%3A%2F%2Fauth.mydomain.com&scope=openid+email+profile&state=9Ld_FtiRpuUpnAAdO26nnJnMRovPhWEIj7MPkgh3UPI 'authelia_ac_ejEmI7FqKWWG2jYY4Kzagu2niepX95dFvDg13RRzGqA.oSRafP55gQnVs50adrhWS8X-I0BxqKJeVGgdkCECXr8'�[39m, params: { at async �[90mfile:///app/�[39msrc/app-openid.js:87:26 { at process.processTicksAndRejections (node:internal/process/task_queues:95:5)�[39m at loginWithOpenIdFinalize �[90m(file:///app/�[39msrc/accounts/openid.js:178:31�[90m)�[39m at Client.callback �[90m(/app/�[39mnode_modules/�[4mopenid-client�[24m/lib/client.js:463:13�[90m)�[39m OpenID grant failed: RPError: iss missing from the response

It appears I was able to fix this by loading config.json using the following response, perhaps it would make sense to update documentation at least for those of us using Authelia. #4029 (comment)

This will change in a near future, the command enable-openid will be removed to avoid this issue

@lelemm commented on GitHub (Mar 3, 2025): > > I'm having an issue with Authelia > > App: v25.3.0 | Server: v25.3.0 > > I use the config.json to config as follows: > > `{ "openId": { "issuer": "https://auth.mydomain.com", "client_id": "actual-budget", "client_secret": "mysecret", "server_hostname": "https://budget.mydomain.com", "authMethod": "oauth2" } }` > > Authelia is setup exactly per the documentation here: > > When I connect through OIDC, I get this error every time: {"status":"error","reason":"openid-grant-failed"} in the browser > > Logs: `GET 400 /openid/callback?code=authelia_ac_ejEmI7FqKWWG2jYY4Kzagu2niepX95dFvDg13RRzGqA.oSRafP55gQnVs50adrhWS8X-I0BxqKJeVGgdkCECXr8&iss=https%3A%2F%2Fauth.mydomain.com&scope=openid+email+profile&state=9Ld_FtiRpuUpnAAdO26nnJnMRovPhWEIj7MPkgh3UPI > > 'authelia_ac_ejEmI7FqKWWG2jYY4Kzagu2niepX95dFvDg13RRzGqA.oSRafP55gQnVs50adrhWS8X-I0BxqKJeVGgdkCECXr8'�[39m, params: { at async �[90mfile:///app/�[39msrc/app-openid.js:87:26 { at process.processTicksAndRejections (node:internal/process/task_queues:95:5)�[39m at loginWithOpenIdFinalize �[90m(file:///app/�[39msrc/accounts/openid.js:178:31�[90m)�[39m at Client.callback �[90m(/app/�[39mnode_modules/�[4mopenid-client�[24m/lib/client.js:463:13�[90m)�[39m OpenID grant failed: RPError: iss missing from the response` > > It appears I was able to fix this by loading config.json using the following response, perhaps it would make sense to update documentation at least for those of us using Authelia. [#4029 (comment)](https://github.com/actualbudget/actual/issues/4029#issuecomment-2561272700) This will change in a near future, the command enable-openid will be removed to avoid this issue
Author
Owner

@atgrey24 commented on GitHub (Mar 3, 2025):

Just set up OpenID and Multi-user and really digging it so far! The big area of improvement I see is SimpleFIN/bank sync integration. Currently, all banks connected to SimpleFIN are visible to all users in the Actual Server. I would like a way to restrict it so that each user only sees their own bank accounts. Let me know if this should be a new feature request instead.

Otherwise, it's working great!

@atgrey24 commented on GitHub (Mar 3, 2025): Just set up OpenID and Multi-user and really digging it so far! The big area of improvement I see is SimpleFIN/bank sync integration. Currently, all banks connected to SimpleFIN are visible to all users in the Actual Server. I would like a way to restrict it so that each user only sees their own bank accounts. Let me know if this should be a new feature request instead. Otherwise, it's working great!
Author
Owner

@lelemm commented on GitHub (Mar 3, 2025):

Just set up OpenID and Multi-user and really digging it so far! The big area of improvement I see is SimpleFIN/bank sync integration. Currently, all banks connected to SimpleFIN are visible to all users in the Actual Server. I would like a way to restrict it so that each user only sees their own bank accounts. Let me know if this should be a new feature request instead.

Otherwise, it's working great!

I was trying to do this, sadly this requires major refactor to gocardless. I will revisit this in the future

@lelemm commented on GitHub (Mar 3, 2025): > Just set up OpenID and Multi-user and really digging it so far! The big area of improvement I see is SimpleFIN/bank sync integration. Currently, all banks connected to SimpleFIN are visible to all users in the Actual Server. I would like a way to restrict it so that each user only sees their own bank accounts. Let me know if this should be a new feature request instead. > > Otherwise, it's working great! I was trying to do this, sadly this requires major refactor to gocardless. I will revisit this in the future
Author
Owner

@atgrey24 commented on GitHub (Mar 3, 2025):

I was trying to do this, sadly this requires major refactor to gocardless. I will revisit this in the future

Is it an issue for both gocardless and simpleFIN, or just the former? I guess it doesn't make sense to fix it on only simpleFIN, even if it was possible.

@atgrey24 commented on GitHub (Mar 3, 2025): > I was trying to do this, sadly this requires major refactor to gocardless. I will revisit this in the future Is it an issue for both gocardless and simpleFIN, or just the former? I guess it doesn't make sense to fix it on only simpleFIN, even if it was possible.
Author
Owner

@lelemm commented on GitHub (Mar 3, 2025):

We would need to rework how keys are stored in the database. This affects all bank sync

I was trying to do this, sadly this requires major refactor to gocardless. I will revisit this in the future

Is it an issue for both gocardless and simpleFIN, or just the former? I guess it doesn't make sense to fix it on only simpleFIN, even if it was possible.

@lelemm commented on GitHub (Mar 3, 2025): We would need to rework how keys are stored in the database. This affects all bank sync > > I was trying to do this, sadly this requires major refactor to gocardless. I will revisit this in the future > > Is it an issue for both gocardless and simpleFIN, or just the former? I guess it doesn't make sense to fix it on only simpleFIN, even if it was possible.
Author
Owner

@Chinoman10 commented on GitHub (Mar 6, 2025):

Came here to share a few things:

  • Setting up OpenID with Google was frustrating because the Actual docs don't specify that the callback URL is https://domain/openid/callback, and Google requires an exact match for redirect URI's; I had to see which URL was being passed as an argument in the Dev Tools and find out about that path and change that...
    • The docs should reflect/inform this...
  • Even with multiple users already created, the login dashboard still says: The first user to login with OpenID will be the server owner. This can't be changed using UI.... and when I look at the User Directory, my openID user is still not displayed as 'Server Owner' (despite the fact that I transferred the ownership to it). Also, on the login page, even with ACTUAL_OPENID_ENFORCE set to true, if I refresh the /login page, it'll still show me the "old" password login (probably since that account is still the server owner for some reason), this might be related to #4509.
@Chinoman10 commented on GitHub (Mar 6, 2025): Came here to share a few things: - Setting up OpenID with Google was frustrating because the Actual docs don't specify that the callback URL is `https://domain/openid/callback`, and Google requires an exact match for redirect URI's; I had to see which URL was being passed as an argument in the Dev Tools and find out about that path and change that... - The docs should reflect/inform this... - Even with multiple users already created, the login dashboard still says: `The first user to login with OpenID will be the server owner. This can't be changed using UI.`... and when I look at the `User Directory`, my openID user is still not displayed as 'Server Owner' (_despite the fact that I transferred the ownership to it_). Also, on the login page, even with `ACTUAL_OPENID_ENFORCE` set to `true`, if I refresh the `/login` page, it'll still show me the "old" password login (_probably since that account is still the server owner for some reason_), this might be related to #4509.
Author
Owner

@lelemm commented on GitHub (Mar 6, 2025):

Thanks for your feedback @Chinoman10

Came here to share a few things:

  • Setting up OpenID with Google was frustrating because the Actual docs don't specify that the callback URL is https://domain/openid/callback, and Google requires an exact match for redirect URI's; I had to see which URL was being passed as an argument in the Dev Tools and find out about that path and change that...

I'm working on improving the docs, but since this experimental feature is new, it's changing a lot. So, I'm holding new docs changes until some more improvements are in, so I don't have to keep changing the docs all the time.

  • The docs should reflect/inform this...
  • Even with multiple users already created, the login dashboard still says: The first user to login with OpenID will be the server owner. This can't be changed using UI.... and when I look at the User Directory, my openID user is still not displayed as 'Server Owner' (despite the fact that I transferred the ownership to it).

This looks like a faulty openid setup, the server owner should be created on first login and never show this warning again. I saw that there is a edge case (I was not able to reproduce it yet tho) that the user gets redirected to actual but no valid token. This causes the faulty configuration (openid enables, but no master user created). I need help to get the right steps to fix this.
Usually, now that you know how to enable with your provider, if you disable and enable again (caution: it will erase all openid users), it will correctly create the server owner on first login

  • Also, on the login page, even with ACTUAL_OPENID_ENFORCE set to true, if I refresh the /login page, it'll still show me the "old" password login (probably since that account is still the server owner for some reason).

There is a bug on ACTUAL_OPENID_ENFORCE. There is a PR to fix this on the way.
https://github.com/actualbudget/actual/pull/4533

@lelemm commented on GitHub (Mar 6, 2025): Thanks for your feedback @Chinoman10 > Came here to share a few things: > > * Setting up OpenID with Google was frustrating because the Actual docs don't specify that the callback URL is `https://domain/openid/callback`, and Google requires an exact match for redirect URI's; I had to see which URL was being passed as an argument in the Dev Tools and find out about that path and change that... I'm working on improving the docs, but since this experimental feature is new, it's changing a lot. So, I'm holding new docs changes until some more improvements are in, so I don't have to keep changing the docs all the time. > > * The docs should reflect/inform this... > * Even with multiple users already created, the login dashboard still says: `The first user to login with OpenID will be the server owner. This can't be changed using UI.`... and when I look at the `User Directory`, my openID user is still not displayed as 'Server Owner' (_despite the fact that I transferred the ownership to it_). This looks like a faulty openid setup, the server owner should be created on first login and never show this warning again. I saw that there is a edge case (I was not able to reproduce it yet tho) that the user gets redirected to actual but no valid token. This causes the faulty configuration (openid enables, but no master user created). I need help to get the right steps to fix this. Usually, now that you know how to enable with your provider, if you disable and enable again (caution: it will erase all openid users), it will correctly create the server owner on first login > * > * Also, on the login page, even with `ACTUAL_OPENID_ENFORCE` set to `true`, if I refresh the `/login` page, it'll still show me the "old" password login (_probably since that account is still the server owner for some reason_). There is a bug on `ACTUAL_OPENID_ENFORCE`. There is a PR to fix this on the way. https://github.com/actualbudget/actual/pull/4533
Author
Owner

@chrisanicolaou commented on GitHub (Mar 10, 2025):

Setup with Authentik, expected difficulty (I'm also new to Authentik).

It was easy & pain-free, especially the integrating with Actual part. For an experimental feature, this felt very polished & stable!

I would also like to agree with @atgrey24's suggestion. Bank sync integration on a per-user basis would be an incredible feat if it were possible.

Thank you for your hard work on this!

@chrisanicolaou commented on GitHub (Mar 10, 2025): Setup with Authentik, expected difficulty (I'm also new to Authentik). It was easy & pain-free, especially the integrating with Actual part. For an experimental feature, this felt very polished & stable! I would also like to agree with @atgrey24's suggestion. Bank sync integration on a per-user basis would be an incredible feat if it were possible. Thank you for your hard work on this!
Author
Owner

@savely-krasovsky commented on GitHub (Mar 11, 2025):

I guess the last thing I am missing is a kind of api keys to securely disable password auth but still be able to integrate with Actual.

@savely-krasovsky commented on GitHub (Mar 11, 2025): I guess the last thing I am missing is a kind of api keys to securely disable password auth but still be able to integrate with Actual.
Author
Owner

@Chinoman10 commented on GitHub (Mar 12, 2025):

This looks like a faulty openid setup, the server owner should be created on first login and never show this warning again. I saw that there is a edge case (I was not able to reproduce it yet tho) that the user gets redirected to actual but no valid token. This causes the faulty configuration (openid enables, but no master user created). I need help to get the right steps to fix this. Usually, now that you know how to enable with your provider, if you disable and enable again (caution: it will erase all openid users), it will correctly create the server owner on first login

Did what you said (disable & reenable via UI), and rebuilt the container, everything was fine integration-wise, but the users had to 'transfer ownership' of their 'orphaned' files back to them, which wasn't that big of a deal.

I have noticed that there is one bug that still remains though.
Every time I force a bank account sync, I get:
Image

Although encryption keys are set, and I can confirm that the other users cannot access my files without the encryption key/password.
I noticed that I can simply ignore this pop-up altogether, since the sync happens anyway, and I tested that encryption is also working.

Note: I'm assuming that the sync also only works when I login (the sync is done client-side, since technically the data has to be decrypted first?), right? Or...? The only way to do a sync on encrypted data is using homomorphic encryption (computation on encrypted data), but that's fairly bleeding edge, so wouldn't expect this to have it 😅 (also, when it's used, it's often "broadcasted" so people know about it).

@Chinoman10 commented on GitHub (Mar 12, 2025): > This looks like a faulty openid setup, the server owner should be created on first login and never show this warning again. I saw that there is a edge case (I was not able to reproduce it yet tho) that the user gets redirected to actual but no valid token. This causes the faulty configuration (openid enables, but no master user created). I need help to get the right steps to fix this. Usually, now that you know how to enable with your provider, if you disable and enable again (caution: it will erase all openid users), it will correctly create the server owner on first login Did what you said (_disable & reenable via UI_), and rebuilt the container, everything was fine integration-wise, but the users had to 'transfer ownership' of their 'orphaned' files back to them, which wasn't that big of a deal. I have noticed that there is one bug that still remains though. Every time I force a bank account sync, I get: ![Image](https://github.com/user-attachments/assets/8b200881-90d1-42c1-a967-02e5ace95e0f) Although encryption keys are set, and I can confirm that the other users cannot access my files without the encryption key/password. I noticed that I can simply ignore this pop-up altogether, since the sync happens anyway, and I tested that encryption is also working. Note: I'm assuming that the sync also only works when I login (_the sync is done client-side, since technically the data has to be decrypted first?_), right? Or...? The only way to do a sync on encrypted data is using homomorphic encryption (_computation on encrypted data_), but that's fairly bleeding edge, so wouldn't expect this to have it 😅 (_also, when it's used, it's often "broadcasted" so people know about it_).
Author
Owner

@saahiljaffer commented on GitHub (Mar 15, 2025):

Hi, I am happy to see the ongoing development of actualbudget and the new addition of SSO using OIDC and OAuth2.0.

I have tested the OpenID feature using the WebUI with Authelia. I get the following error:

{"status":"error","reason":"openid-grant-failed"}

2025-01-08T17:23:08.575Z info: GET 400 /openid/callback?code=authelia_ac_<redacted>&iss=https%3A%2F%2Fauth.example.com&scope=openid+email+profile&state=2gbbP-UK8xj2Gs2pcfRnI724JWRzgTIw_3YSqxqIP7c
OpenID grant failed: RPError: iss missing from the response
    at Client.callback (/app/node_modules/openid-client/lib/client.js:436:13)
    at loginWithOpenIdFinalize (file:///app/src/accounts/openid.js:177:31)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async file:///app/src/app-openid.js:86:24 {
  params: {
    code: 'authelia_ac_<redacted>',
    state: '2gbbP-UK8xj2Gs2pcfRnI724JWRzgTIw_3YSqxqIP7c'
  }
}

To me, this looks like actual is expecting the iss (issuer) parameter to be present in the Authentication Response. However the iss parameter is not required to be present in the response by section 3.1.2.5 of the openid standard or section 4.1.2 of the oauth2.0 standard. Authelia correctly encodes the iss parameter in the IDToken as required.

Actually authelia supports RFC9207 which basically only implements the iss parameter in the Authrization Response. However there must be some sort of issue either in the library used or the implementation where the iss validation fails. The parameter is included in the authelia response:

https://actual.example.com/openid/callback?code=authelia_ac_<redacted>&iss=https%3A%2F%2Fauth.example.com&scope=openid+email+profile&state=2gbbP-UK8xj2Gs2pcfRnI724JWRzgTIw_3YSqxqIP7c

It is possible that I interpreted the error wrong, but I think this might be a bug.

Authelia oidc client configuration for reference:

identity_providers:
oidc:
clients:
- client_id: 'actual'
client_name: 'actual'
client_secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng' # The digest of 'insecure_secret'.
public: false
require_pkce: true
pkce_challenge_method: 'S256'
authorization_policy: 'two_factor'
redirect_uris:
- 'https://actual.example.com/openid/callback'
scopes:
- 'openid'
- 'profile'
- 'email'
userinfo_signed_response_alg: 'none'

Looks like actual isn't passing the iss parameter to the library so it thinks it's missing. I've created a PR to fix this.

@saahiljaffer commented on GitHub (Mar 15, 2025): > Hi, I am happy to see the ongoing development of actualbudget and the new addition of SSO using OIDC and OAuth2.0. > > I have tested the OpenID feature using the WebUI with Authelia. I get the following error: > > {"status":"error","reason":"openid-grant-failed"} > ``` > 2025-01-08T17:23:08.575Z info: GET 400 /openid/callback?code=authelia_ac_<redacted>&iss=https%3A%2F%2Fauth.example.com&scope=openid+email+profile&state=2gbbP-UK8xj2Gs2pcfRnI724JWRzgTIw_3YSqxqIP7c > OpenID grant failed: RPError: iss missing from the response > at Client.callback (/app/node_modules/openid-client/lib/client.js:436:13) > at loginWithOpenIdFinalize (file:///app/src/accounts/openid.js:177:31) > at process.processTicksAndRejections (node:internal/process/task_queues:95:5) > at async file:///app/src/app-openid.js:86:24 { > params: { > code: 'authelia_ac_<redacted>', > state: '2gbbP-UK8xj2Gs2pcfRnI724JWRzgTIw_3YSqxqIP7c' > } > } > ``` > > To me, this looks like actual is expecting the `iss` (issuer) parameter to be present in the Authentication Response. ~However the `iss` parameter is not required to be present in the response by section 3.1.2.5 of the [openid standard](https://openid.net/specs/openid-connect-core-1_0.html#AuthResponse) or section 4.1.2 of the [oauth2.0 standard](https://www.rfc-editor.org/rfc/rfc6749.html#section-4.1.2). Authelia correctly encodes the `iss` parameter in the [IDToken](https://openid.net/specs/openid-connect-core-1_0.html#IDToken) as required.~ > > Actually authelia supports [RFC9207](https://datatracker.ietf.org/doc/html/rfc9207) which basically only implements the `iss` parameter in the Authrization Response. However there must be some sort of issue either in the library used or the implementation where the `iss` validation fails. The parameter is included in the authelia response: > > ``` > https://actual.example.com/openid/callback?code=authelia_ac_<redacted>&iss=https%3A%2F%2Fauth.example.com&scope=openid+email+profile&state=2gbbP-UK8xj2Gs2pcfRnI724JWRzgTIw_3YSqxqIP7c > ``` > > It is possible that I interpreted the error wrong, but I think this might be a bug. > > Authelia oidc client configuration for reference: > > identity_providers: > oidc: > clients: > - client_id: 'actual' > client_name: 'actual' > client_secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng' # The digest of 'insecure_secret'. > public: false > require_pkce: true > pkce_challenge_method: 'S256' > authorization_policy: 'two_factor' > redirect_uris: > - 'https://actual.example.com/openid/callback' > scopes: > - 'openid' > - 'profile' > - 'email' > userinfo_signed_response_alg: 'none' Looks like actual isn't passing the iss parameter to the library so it thinks it's missing. I've created a [PR](https://github.com/actualbudget/actual/pull/4626) to fix this.
Author
Owner

@anderspitman commented on GitHub (Mar 17, 2025):

Thank you for implementing this @lelemm!

It was pretty easy to get working on PikaPods with LastLogin (my project - https://lastlogin.net/) as provider.

No rush, but one feature request I have would be similar to @ishanjain28's redirect request. If you were to implement forward auth (aka trusted header auth - https://www.authelia.com/integration/trusted-header-sso/introduction/), the UX would be even more seamless. If the user is already signed in to the auth server, the username can be passed through as an HTTP header. If Actual trusts the header, then no additional login is necessary. In practice, this lets you log into your auth provider once, then any app that supports forward auth is automatically logged in.

@anderspitman commented on GitHub (Mar 17, 2025): Thank you for implementing this @lelemm! It was pretty easy to get working on PikaPods with LastLogin (my project - https://lastlogin.net/) as provider. No rush, but one feature request I have would be similar to @ishanjain28's redirect request. If you were to implement forward auth (aka trusted header auth - https://www.authelia.com/integration/trusted-header-sso/introduction/), the UX would be even more seamless. If the user is already signed in to the auth server, the username can be passed through as an HTTP header. If Actual trusts the header, then no additional login is necessary. In practice, this lets you log into your auth provider once, then any app that supports forward auth is automatically logged in.
Author
Owner

@oddlama commented on GitHub (Mar 22, 2025):

The current documentation doesn't reflect that I need to run a enable-openid script to use the configuration from the json file or from the environment. It took me a while to realize this, since it is only mentioned in a single comment in this comment thread. Is there a reason why I need to do that at all? Why can actual not automatically enable openid when the configuration variables are set?

The current process makes it impossible to automatically setup a new server with openid. Theres always a manual step involved even though all the relevant information already exists.

Another thing that I noticed is that the configuration variables are just copied into the database once, so if they are changed in the future, this will not be reflected by actual unless someone manually calls disable-openid and enable-openid.

@oddlama commented on GitHub (Mar 22, 2025): The current documentation doesn't reflect that I need to run a `enable-openid` script to use the configuration from the json file or from the environment. It took me a while to realize this, since it is only mentioned in a single comment in this comment thread. Is there a reason why I need to do that at all? Why can actual not automatically enable openid when the configuration variables are set? The current process makes it impossible to automatically setup a new server with openid. Theres always a manual step involved even though all the relevant information already exists. Another thing that I noticed is that the configuration variables are just copied into the database once, so if they are changed in the future, this will not be reflected by actual unless someone manually calls disable-openid and enable-openid.
Author
Owner

@imryanslade commented on GitHub (Mar 26, 2025):

Can someone review #4626?

@imryanslade commented on GitHub (Mar 26, 2025): Can someone review #4626?
Author
Owner

@lelemm commented on GitHub (Mar 26, 2025):

Can someone review #4626?

I want to review and test this with authelia but I don't use it.
If you do, can you share a basic configuration.yml so I can run authelia with openid support quick?

@lelemm commented on GitHub (Mar 26, 2025): > Can someone review [#4626](https://github.com/actualbudget/actual/pull/4626)? I want to review and test this with `authelia` but I don't use it. If you do, can you share a basic `configuration.yml` so I can run authelia with openid support quick?
Author
Owner

@lelemm commented on GitHub (Mar 26, 2025):

Can someone review #4626?

I want to review and test this with authelia but I don't use it. If you do, can you share a basic configuration.yml so I can run authelia with openid support quick?

I was able to run it with openid

@lelemm commented on GitHub (Mar 26, 2025): > > Can someone review [#4626](https://github.com/actualbudget/actual/pull/4626)? > > I want to review and test this with `authelia` but I don't use it. If you do, can you share a basic `configuration.yml` so I can run authelia with openid support quick? I was able to run it with openid
Author
Owner

@imryanslade commented on GitHub (Mar 26, 2025):

@lelemm can you share the config that worked for you? I still get the 'grant failed' error.

@imryanslade commented on GitHub (Mar 26, 2025): @lelemm can you share the config that worked for you? I still get the 'grant failed' error.
Author
Owner

@lelemm commented on GitHub (Mar 26, 2025):

@lelemm can you share the config that worked for you? I still get the 'grant failed' error.

server:
  address: tcp://0.0.0.0:9091

log:
  level: debug

authentication_backend:
  file:
    path: /config/users.yml

access_control:
  default_policy: one_factor
  rules:
    - domain: "*"
      policy: one_factor

session:
  name: authelia_session
  secret: insecure_session_secret
  expiration: 3600
  inactivity: 300
  remember_me: 1M
  cookies:
    - domain: [redacted]
      authelia_url: [redacted]

storage:
  encryption_key: insecure_storage_key
  local:
    path: /config/db.sqlite3

notifier:
  filesystem:
    filename: /config/notification.txt

identity_validation:
  reset_password:
    jwt_secret: insecure_jwt_secret

telemetry:
  metrics:
    enabled: false

theme: dark

identity_providers:
  oidc:
    issuer_private_key: |
      -----BEGIN PRIVATE KEY-----
      MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDHZSqMn7A6X3oz
      VxnmioTC0HnRuouqVmU6Cf9WTmdxeRec9b9ZR+Hmo1/MZXCb+sIHTep49b59v8Db
      DfV74h4I59LE0hco4CLKFE+BRksjY9CbEr5ymiGN57hxmbLDGZt1ylGYiXcstINB
      nLhINAADDMOF63pqUE09E2ZXGS8jpkH78eghC7RsHQDUbVoHqnOjZHX/SUTDzHTQ
      kA/BmJLYseMVXLcV18xEb69J+hrC6+gBvf3VFwxTDhzYUc9wHaVq0DTTTfWwaUip
      QMCR0MDMpPkqJncP7X6eZ1dSN4t4ioeVcHYmeybmKfVdBoc6Hl2w1bayy4OnovIz
      V1YC6lGXAgMBAAECggEAToCL8fVk4nZ4nAHs1pEul6yQaXvyRMvi6qjI+GfB3jD4
      lPlDrpjYXX9w1f4SCbb98PZCHAFUUBnQie3C+lUZ0hPDLW4xZAxqZfj9HD5aksJX
      fNYyWNhJ4Z6bRU5nzNwmEofm/BES9GzVSF21R+gBITJDQFRnS7f10Nf0cNIfdv7p
      TbJW3aZqNgAVL4Ga3BAocsCHjjxng7rOz6TYu1dokBcVnNOsCkotvJlj0v6L6Ead
      neCt60aUfzdd2EWz6hPicIiAntpRu+mnEuMRXx+h1GPcP2nPRbhMtASTZE6xs8oW
      Zb8tXyzLoig+NJfD/6FFmnnGOvPkYvAUPoPSP0yQAQKBgQD3077lReIxHy/ItIVc
      s7YFD6uNTIWgFqVxSWgqS9SVHYNzfNQ+hB60bnQT8enubelofg9SP8R/8fNsbHvL
      WH19Fmv2I5DEkTfWidCJbLYf3oH/cpfKUXI/zBT+TM+pTBq+5+F0+xd+5WZhasRB
      /AZfWDoFTmkSjJJJhGIDttI8AQKBgQDN+In1nuKN33ensD1K9W40uXRtIC5nQniQ
      nDaOkFWkj0+jDPs8mlAkF2U6qbwqwZuNLn3WbPnPkjfUH4XOmLqai1Qj8aZJaGvl
      DPFfqc6PMKKP9XLJuFqjccVOeboiZuXATkE/N2SUtKppsP5/04qyNZxNE4+hwOlq
      r8qC+1ztlwKBgQCfczdhYGM147Dk23Dqwh2ciAaCdPeMlsV/bBF/FScDgeeviGMu
      jecLg/1fT8iJRWJlfqXw72JIR62s1ueXX6ntr11rElr0fdKFUEpCARX0zz6o0lvj
      Kh/t+CqRq234qSSUK7EdiOgHFyWWDBGVuseG1McP3vEvpA4DCw/c/+WoAQKBgFOv
      DkZYJo4j5BaieVSyQPN1AgOwVoonrJp8jYIAzHsOqvmBNbZasALp6nwaKFRq0wta
      f1AWeKzIKJyrrg7RaMePokD0Vm5u2Z93Ub5fXIg652F8BQZGO7U6bULEHEcL7X7j
      jIjltZzhhndorQ48YZakR3vdXbcHjQ6Gm8352LjDAoGBALD4TfukfeqJgqOZ30Ba
      5IEx80XnWqp6SXckz3piu15jqlXZ0XlufgGxmMtblx9qPLBvxNLxSjFA0fNzTPGL
      14wHXwH6JMzx6HZP8ime35W6VckRIiiiTKPFsclU9adPumGKLsIVd+Y4obG97ojI
      3ljrO2bZdQIbL9zlPLzO7whC
      -----END PRIVATE KEY-----
    cors:
      endpoints:
        - authorization
        - token
        - revocation
        - introspection
        - userinfo
      allowed_origins:
        - http://localhost:5006/
    clients:
      - id: myclient
        description: My test client
        secret: mysecret
        public: false
        authorization_policy: one_factor
        redirect_uris:
          - http://localhost:5006/openid/callback
        scopes:
          - openid
          - profile
          - email
        grant_types:
          - authorization_code
        response_types:
          - code

please, don't use the same private key if someone is using this config as base

@lelemm commented on GitHub (Mar 26, 2025): > [@lelemm](https://github.com/lelemm) can you share the config that worked for you? I still get the 'grant failed' error. ```yaml server: address: tcp://0.0.0.0:9091 log: level: debug authentication_backend: file: path: /config/users.yml access_control: default_policy: one_factor rules: - domain: "*" policy: one_factor session: name: authelia_session secret: insecure_session_secret expiration: 3600 inactivity: 300 remember_me: 1M cookies: - domain: [redacted] authelia_url: [redacted] storage: encryption_key: insecure_storage_key local: path: /config/db.sqlite3 notifier: filesystem: filename: /config/notification.txt identity_validation: reset_password: jwt_secret: insecure_jwt_secret telemetry: metrics: enabled: false theme: dark identity_providers: oidc: issuer_private_key: | -----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDHZSqMn7A6X3oz VxnmioTC0HnRuouqVmU6Cf9WTmdxeRec9b9ZR+Hmo1/MZXCb+sIHTep49b59v8Db DfV74h4I59LE0hco4CLKFE+BRksjY9CbEr5ymiGN57hxmbLDGZt1ylGYiXcstINB nLhINAADDMOF63pqUE09E2ZXGS8jpkH78eghC7RsHQDUbVoHqnOjZHX/SUTDzHTQ kA/BmJLYseMVXLcV18xEb69J+hrC6+gBvf3VFwxTDhzYUc9wHaVq0DTTTfWwaUip QMCR0MDMpPkqJncP7X6eZ1dSN4t4ioeVcHYmeybmKfVdBoc6Hl2w1bayy4OnovIz V1YC6lGXAgMBAAECggEAToCL8fVk4nZ4nAHs1pEul6yQaXvyRMvi6qjI+GfB3jD4 lPlDrpjYXX9w1f4SCbb98PZCHAFUUBnQie3C+lUZ0hPDLW4xZAxqZfj9HD5aksJX fNYyWNhJ4Z6bRU5nzNwmEofm/BES9GzVSF21R+gBITJDQFRnS7f10Nf0cNIfdv7p TbJW3aZqNgAVL4Ga3BAocsCHjjxng7rOz6TYu1dokBcVnNOsCkotvJlj0v6L6Ead neCt60aUfzdd2EWz6hPicIiAntpRu+mnEuMRXx+h1GPcP2nPRbhMtASTZE6xs8oW Zb8tXyzLoig+NJfD/6FFmnnGOvPkYvAUPoPSP0yQAQKBgQD3077lReIxHy/ItIVc s7YFD6uNTIWgFqVxSWgqS9SVHYNzfNQ+hB60bnQT8enubelofg9SP8R/8fNsbHvL WH19Fmv2I5DEkTfWidCJbLYf3oH/cpfKUXI/zBT+TM+pTBq+5+F0+xd+5WZhasRB /AZfWDoFTmkSjJJJhGIDttI8AQKBgQDN+In1nuKN33ensD1K9W40uXRtIC5nQniQ nDaOkFWkj0+jDPs8mlAkF2U6qbwqwZuNLn3WbPnPkjfUH4XOmLqai1Qj8aZJaGvl DPFfqc6PMKKP9XLJuFqjccVOeboiZuXATkE/N2SUtKppsP5/04qyNZxNE4+hwOlq r8qC+1ztlwKBgQCfczdhYGM147Dk23Dqwh2ciAaCdPeMlsV/bBF/FScDgeeviGMu jecLg/1fT8iJRWJlfqXw72JIR62s1ueXX6ntr11rElr0fdKFUEpCARX0zz6o0lvj Kh/t+CqRq234qSSUK7EdiOgHFyWWDBGVuseG1McP3vEvpA4DCw/c/+WoAQKBgFOv DkZYJo4j5BaieVSyQPN1AgOwVoonrJp8jYIAzHsOqvmBNbZasALp6nwaKFRq0wta f1AWeKzIKJyrrg7RaMePokD0Vm5u2Z93Ub5fXIg652F8BQZGO7U6bULEHEcL7X7j jIjltZzhhndorQ48YZakR3vdXbcHjQ6Gm8352LjDAoGBALD4TfukfeqJgqOZ30Ba 5IEx80XnWqp6SXckz3piu15jqlXZ0XlufgGxmMtblx9qPLBvxNLxSjFA0fNzTPGL 14wHXwH6JMzx6HZP8ime35W6VckRIiiiTKPFsclU9adPumGKLsIVd+Y4obG97ojI 3ljrO2bZdQIbL9zlPLzO7whC -----END PRIVATE KEY----- cors: endpoints: - authorization - token - revocation - introspection - userinfo allowed_origins: - http://localhost:5006/ clients: - id: myclient description: My test client secret: mysecret public: false authorization_policy: one_factor redirect_uris: - http://localhost:5006/openid/callback scopes: - openid - profile - email grant_types: - authorization_code response_types: - code ``` please, don't use the same private key if someone is using this config as base
Author
Owner

@imryanslade commented on GitHub (Mar 26, 2025):

@lelemm that PR should fix it 100%, it's a very simple bug. Just an issuer field "iss" not being parsed from the callback url. Example URL that my Authelia instance sends to actual server:

https://actual.myserver.com/openid/callback?code=authelia_ac_mRkoQ...&iss=...&scope=openid+email+profile&state=...abc

As you can see "iss" field is present but my actual server throws this error:

OpenID grant failed: RPError: iss missing from the response
    at Client.callback (/app/node_modules/openid-client/lib/client.js:463:13)
    at loginWithOpenIdFinalize (file:///app/src/accounts/openid.js:178:31)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async file:///app/src/app-openid.js:87:26 {
  params: {
    code: 'authelia_ac_mRkoQK...',
    state: '...'
  }
}

It seems that it only picks out code and state out of the redirect URL.

@imryanslade commented on GitHub (Mar 26, 2025): @lelemm that PR should fix it 100%, it's a very simple bug. Just an issuer field "iss" not being parsed from the callback url. Example URL that my Authelia instance sends to actual server: https://actual.myserver.com/openid/callback?code=authelia_ac_mRkoQ...&iss=...&scope=openid+email+profile&state=...abc As you can see "iss" field is present but my actual server throws this error: ``` OpenID grant failed: RPError: iss missing from the response at Client.callback (/app/node_modules/openid-client/lib/client.js:463:13) at loginWithOpenIdFinalize (file:///app/src/accounts/openid.js:178:31) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async file:///app/src/app-openid.js:87:26 { params: { code: 'authelia_ac_mRkoQK...', state: '...' } } ``` It seems that it only picks out code and state out of the redirect URL.
Author
Owner

@imryanslade commented on GitHub (Mar 26, 2025):

@lelemm Below is my Authelia configuration (rest is almost exact same as yours). I tried your client configuration as well, but no luck. Still getting the {"status":"error","reason":"openid-grant-failed"}.

         - client_id: 'actual'
           client_name: 'Actual'
           client_secret: {{ secret "/secrets/APP_SECRET_ACTUAL" }}
           public: 'false'
           authorization_policy: 'actual'
           redirect_uris:
             - 'https://actual.myserver.com/openid/callback'
           scopes:
             - 'openid'
             - 'email'
             - 'profile'
             - 'groups'
           grant_types:
             - 'authorization_code'
           response_types:
             - 'code'
           userinfo_signed_response_alg: 'none'
           token_endpoint_auth_method: 'client_secret_basic'

Additionally I tried leaving last two params out, and still got the error.

           userinfo_signed_response_alg: 'none'
           token_endpoint_auth_method: 'client_secret_basic'

Redirect URI comes with all parameters needed by Actual, iss + code + state. But it just doesn't take it from the URL.

@imryanslade commented on GitHub (Mar 26, 2025): @lelemm Below is my Authelia configuration (rest is almost exact same as yours). I tried your client configuration as well, but no luck. Still getting the `{"status":"error","reason":"openid-grant-failed"}`. ``` - client_id: 'actual' client_name: 'Actual' client_secret: {{ secret "/secrets/APP_SECRET_ACTUAL" }} public: 'false' authorization_policy: 'actual' redirect_uris: - 'https://actual.myserver.com/openid/callback' scopes: - 'openid' - 'email' - 'profile' - 'groups' grant_types: - 'authorization_code' response_types: - 'code' userinfo_signed_response_alg: 'none' token_endpoint_auth_method: 'client_secret_basic' ``` Additionally I tried leaving last two params out, and still got the error. ``` userinfo_signed_response_alg: 'none' token_endpoint_auth_method: 'client_secret_basic' ``` Redirect URI comes with all parameters needed by Actual, iss + code + state. But it just doesn't take it from the URL.
Author
Owner

@lelemm commented on GitHub (Mar 26, 2025):

I'm reviewing the PR. asked for changes, they already changed.
when I said this:

I was able to run it with openid

I was talking about Authelia, not Actual

@lelemm commented on GitHub (Mar 26, 2025): I'm reviewing the PR. asked for changes, they already changed. when I said this: > I was able to run it with openid I was talking about Authelia, not Actual
Author
Owner

@imryanslade commented on GitHub (Mar 26, 2025):

Sounds good, thank you. I also just applied the one liner from @saahiljaffer straight into the src/accounts/openid.js from the latest release and it worked perfectly!
Thanks @saahiljaffer for taking the time!

@imryanslade commented on GitHub (Mar 26, 2025): Sounds good, thank you. I also just applied the one liner from @saahiljaffer straight into the `src/accounts/openid.js` from the latest release and it worked perfectly! Thanks @saahiljaffer for taking the time!
Author
Owner

@MatissJanis commented on GitHub (Mar 28, 2025):

Multi-user issue reported here: https://github.com/actualbudget/actual/issues/4441

@MatissJanis commented on GitHub (Mar 28, 2025): Multi-user issue reported here: https://github.com/actualbudget/actual/issues/4441
Author
Owner

@Rihan9 commented on GitHub (Mar 28, 2025):

Hi all,
I applied the fix on PR #4626 and worked for the first user. The second user instead can't login.
In the log I have the following error:

2025-03-28T16:38:48.647Z info: GET 400 /openid/callback?code=authelia_ac_{{OMITTED}}&iss=https%3A%2F%2F{{OMITTED}}&scope=openid+email+profile&state={{OMITTED}}
OpenID grant failed: OPError: invalid_grant (The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client. The authorization code has already been used.)
    at Client.grant (/app/node_modules/openid-client/lib/client.js:1381:22)
    at processResponse (/app/node_modules/openid-client/lib/helpers/process_response.js:38:13)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Client.callback (/app/node_modules/openid-client/lib/client.js:520:24)
    at async file:///app/src/app-openid.js:87:26 {
    at async loginWithOpenIdFinalize (file:///app/src/accounts/openid.js:178:18)
  error: 'invalid_grant',
  error_description: 'The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client. The authorization code has already been used.'
}
@Rihan9 commented on GitHub (Mar 28, 2025): Hi all, I applied the fix on PR #4626 and worked for the first user. The second user instead can't login. In the log I have the following error: ``` 2025-03-28T16:38:48.647Z info: GET 400 /openid/callback?code=authelia_ac_{{OMITTED}}&iss=https%3A%2F%2F{{OMITTED}}&scope=openid+email+profile&state={{OMITTED}} OpenID grant failed: OPError: invalid_grant (The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client. The authorization code has already been used.) at Client.grant (/app/node_modules/openid-client/lib/client.js:1381:22) at processResponse (/app/node_modules/openid-client/lib/helpers/process_response.js:38:13) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async Client.callback (/app/node_modules/openid-client/lib/client.js:520:24) at async file:///app/src/app-openid.js:87:26 { at async loginWithOpenIdFinalize (file:///app/src/accounts/openid.js:178:18) error: 'invalid_grant', error_description: 'The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client. The authorization code has already been used.' } ```
Author
Owner

@Rihan9 commented on GitHub (Mar 28, 2025):

I solved the problem in my latest comment by adding the second user before letting her log in. I don't know if it's the correct operation or a workaround

@Rihan9 commented on GitHub (Mar 28, 2025): I solved the problem in my latest comment by adding the second user before letting her log in. I don't know if it's the correct operation or a workaround
Author
Owner

@lelemm commented on GitHub (Mar 28, 2025):

I solved the problem in my latest comment by adding the second user before letting her log in. I don't know if it's the correct operation or a workaround

For the current flow, you must add the user to the user directory before login

@lelemm commented on GitHub (Mar 28, 2025): > I solved the problem in my latest comment by adding the second user before letting her log in. I don't know if it's the correct operation or a workaround For the current flow, you must add the user to the user directory before login
Author
Owner

@hobbit44 commented on GitHub (Mar 31, 2025):

Got an issue with login redirection: #4488

@hobbit44 commented on GitHub (Mar 31, 2025): Got an issue with login redirection: [#4488](https://github.com/actualbudget/actual/issues/4488#issuecomment-2767210334)
Author
Owner

@delize commented on GitHub (Apr 5, 2025):

The path listed in the doc:

When configuring your OpenID provider, be sure to register the following redirect URI with the provider: https://<your-domain.tld>/path/openid/callback

Doesn't appear to be correct.

Shouldn't this be: https://<your-domain.tld>/openid/callback

This is what it looks like when checking Docker Container Logs:

2025-04-05T18:43:19.428Z info: POST 200 /account/login
2025-04-05T18:43:20.315Z info: GET 400 /openid/callback?state={OMIT}&error=access_denied&error_description=User+is+not+assigned+to+the+client+application.
Logging in via openid
2025-04-05T18:43:46.916Z info: POST 200 /account/login
Deleted 0 old sessions
2025-04-05T18:43:56.382Z info: GET 302 /openid/callback?code={OMIT}`

Additionally, Okta works as a Provider.

@delize commented on GitHub (Apr 5, 2025): The path listed in the [doc](https://actualbudget.org/docs/experimental/oauth-auth#configuring-openid-using-the-ui): > When configuring your OpenID provider, be sure to register the following redirect URI with the provider: https://<your-domain.tld>/path/openid/callback Doesn't appear to be correct. Shouldn't this be: `https://<your-domain.tld>/openid/callback` This is what it looks like when checking Docker Container Logs: ``` 2025-04-05T18:43:19.428Z info: POST 200 /account/login 2025-04-05T18:43:20.315Z info: GET 400 /openid/callback?state={OMIT}&error=access_denied&error_description=User+is+not+assigned+to+the+client+application. Logging in via openid 2025-04-05T18:43:46.916Z info: POST 200 /account/login Deleted 0 old sessions 2025-04-05T18:43:56.382Z info: GET 302 /openid/callback?code={OMIT}` ``` Additionally, Okta works as a Provider.
Author
Owner

@Crispychickenlegs commented on GitHub (Apr 6, 2025):

Hello,

After the latest update, this seems to be broken.

If you make a mistake in the OpenID config when setting it up, the only way you can fix this seems to be to login with password, disable OpenID, then reenable it with the updated config.

Changing the config by clicking on 'Review OpenID configuration' on the initial sign in screen has no effect. It takes you to the form to change the config, but after submitting the broken config is still used.

Image

Image

@Crispychickenlegs commented on GitHub (Apr 6, 2025): Hello, After the latest update, this seems to be broken. If you make a mistake in the OpenID config when setting it up, the only way you can fix this seems to be to login with password, disable OpenID, then reenable it with the updated config. Changing the config by clicking on 'Review OpenID configuration' on the initial sign in screen has no effect. It takes you to the form to change the config, but after submitting the broken config is still used. ![Image](https://github.com/user-attachments/assets/65c3b9b6-bc51-4ebf-bfc8-9e060bfd56da) ![Image](https://github.com/user-attachments/assets/c33452ba-5e29-4605-9d63-7ba39a6c08da)
Author
Owner

@lelemm commented on GitHub (Apr 8, 2025):

Hello,

After the latest update, this seems to be broken.

If you make a mistake in the OpenID config when setting it up, the only way you can fix this seems to be to login with password, disable OpenID, then reenable it with the updated config.

Changing the config by clicking on 'Review OpenID configuration' on the initial sign in screen has no effect. It takes you to the form to change the config, but after submitting the broken config is still used.

Image

Image

The [Review OpenID configuration] does not show the values (it's fixed on a PR not approved yet), but it saves the value properly

@lelemm commented on GitHub (Apr 8, 2025): > Hello, > > After the latest update, this seems to be broken. > > If you make a mistake in the OpenID config when setting it up, the only way you can fix this seems to be to login with password, disable OpenID, then reenable it with the updated config. > > Changing the config by clicking on 'Review OpenID configuration' on the initial sign in screen has no effect. It takes you to the form to change the config, but after submitting the broken config is still used. > > ![Image](https://github.com/user-attachments/assets/65c3b9b6-bc51-4ebf-bfc8-9e060bfd56da) > > ![Image](https://github.com/user-attachments/assets/c33452ba-5e29-4605-9d63-7ba39a6c08da) The [Review OpenID configuration] does not show the values (it's fixed on a PR not approved yet), but it saves the value properly
Author
Owner

@Crispychickenlegs commented on GitHub (Apr 8, 2025):

The [Review OpenID configuration] does not show the values (it's fixed on a PR not approved yet), but it saves the value properly

That's not the experience I have had. The screenshots were just to show which part I was talking about.

The issue I was having was that the values didn't seem to be saving properly when reviewing after incorrect config was entered initially.

Scenario:

  1. Login to Actual using password.
  2. Enable OpenID in Actual settings and enter the (incorrect) config details.
  3. Logout
  4. Attempt to login using OpenID - Fails
  5. Click Review OpenID configuration
  6. Re-enter the Correct config and click OK.
  7. Attempt to login - Fails
  8. Login using Password.
  9. Disable OpenID
  10. Re-enable OpenID using the correct config.
  11. Logout
  12. Login using OpenID - Success

I'm not 100% sure where to find the config on the backend to see if the details are actually being changed when reviewing. Perhaps they are as you say and something else is going on, but I can't be certain.

@Crispychickenlegs commented on GitHub (Apr 8, 2025): > The [Review OpenID configuration] does not show the values (it's fixed on a PR not approved yet), but it saves the value properly That's not the experience I have had. The screenshots were just to show which part I was talking about. The issue I was having was that the values didn't seem to be saving properly when reviewing after incorrect config was entered initially. Scenario: 1. Login to Actual using password. 2. Enable OpenID in Actual settings and enter the (incorrect) config details. 3. Logout 4. Attempt to login using OpenID - Fails 7. Click Review OpenID configuration 8. Re-enter the Correct config and click OK. 9. Attempt to login - Fails 12. Login using Password. 13. Disable OpenID 14. Re-enable OpenID using the correct config. 15. Logout 16. Login using OpenID - Success I'm not 100% sure where to find the config on the backend to see if the details are actually being changed when reviewing. Perhaps they are as you say and something else is going on, but I can't be certain.
Author
Owner

@delize commented on GitHub (Apr 12, 2025):

Have been having issues today with logging out, and, accessing my actual instance a week or so after logging in.

When logging in, the server either states "trouble syncing", "trouble connecting", "error accessing" or some extent.

Image
Image

And just sits here.

When trying to close the budget file, I then end up here:

Image

For a while. Eventually, something times out... and then I am sitting here:

Image

With the budget file selector briefly appearing and disappearing every 30 seconds or so.

Now, with all that said, if I clear cookies... I can login without any issue.

PostError: PostError: unauthorized
    at throwIfNot200 (post.ts:16:13)
    at postBinary (post.ts:211:3)
    at async _fullSync (index.ts:662:21)
    at async index.ts:561:16
    at async app_sync (app.ts:20:10)
index.ts:593 PostError: PostError: unauthorized
    at throwIfNot200 (post.ts:16:13)
    at postBinary (post.ts:211:3)
    at async _fullSync (index.ts:662:21)
    at async index.ts:561:16
    at async app_sync (app.ts:20:10)
cloud-storage.ts:385 Unexpected error fetching file list from server HTTPError: HTTPError: unsuccessful status code (401): {"status":"error","reason":"unauthorized","details":"token-not-found"}
    at cloud-storage.ts:57:13
    at async fetchJSON (cloud-storage.ts:66:9)
    at async listRemoteFiles (cloud-storage.ts:379:11)

Is what I see in the console log.

Once I clear cookies, "Server online" immediately appears instead of syncing. Then am presented with:

Image

Seems like their needs to be some UI / Timeout issues resolved in the authentication, or maybe I don't have a specific OIDC claim enabled, but, something appears to be missing / being buggy.

EDIT:

Just to add more technical aspects.

  • I have nginx (SWAG specifically) in front of budget
  • No other authentication methods infront of budget with OIDC enabled
  • Using Desktop Browsers as the client, not any desktop app or form of that
  • I do SSO/IAM related stuff, so I am fairly confident that this is setup correctly, the only thing currently missing which I believe is in the plans is the Single Logout / Logout entry point.
  • Only way to resolve the above is clear cookies and cache for the site (on a subdomain).
@delize commented on GitHub (Apr 12, 2025): Have been having issues today with logging out, and, accessing my actual instance a week or so after logging in. When logging in, the server either states "trouble syncing", "trouble connecting", "error accessing" or some extent. ![Image](https://github.com/user-attachments/assets/aee06d58-5bae-478b-9c45-c1a2e03d7aa8) <img width="359" alt="Image" src="https://github.com/user-attachments/assets/93abfa3f-65a8-4889-9d7e-98a0b6bc48ce" /> And just sits here. When trying to close the budget file, I then end up here: ![Image](https://github.com/user-attachments/assets/afebb8d5-d941-457a-a96b-349ad608d6d4) For a while. Eventually, something times out... and then I am sitting here: <img width="996" alt="Image" src="https://github.com/user-attachments/assets/77e38f6e-59a1-40a8-8c80-889e4bdc2336" /> With the budget file selector briefly appearing and disappearing every 30 seconds or so. Now, with all that said, if I clear cookies... I can login without any issue. ``` PostError: PostError: unauthorized at throwIfNot200 (post.ts:16:13) at postBinary (post.ts:211:3) at async _fullSync (index.ts:662:21) at async index.ts:561:16 at async app_sync (app.ts:20:10) index.ts:593 PostError: PostError: unauthorized at throwIfNot200 (post.ts:16:13) at postBinary (post.ts:211:3) at async _fullSync (index.ts:662:21) at async index.ts:561:16 at async app_sync (app.ts:20:10) cloud-storage.ts:385 Unexpected error fetching file list from server HTTPError: HTTPError: unsuccessful status code (401): {"status":"error","reason":"unauthorized","details":"token-not-found"} at cloud-storage.ts:57:13 at async fetchJSON (cloud-storage.ts:66:9) at async listRemoteFiles (cloud-storage.ts:379:11) ``` Is what I see in the console log. Once I clear cookies, "Server online" immediately appears instead of syncing. Then am presented with: <img width="676" alt="Image" src="https://github.com/user-attachments/assets/ae8d5f98-568b-49f5-9a3f-5ec94d35ac09" /> Seems like their needs to be some UI / Timeout issues resolved in the authentication, or maybe I don't have a specific OIDC claim enabled, but, something appears to be missing / being buggy. EDIT: Just to add more technical aspects. - I have nginx (SWAG specifically) in front of budget - No other authentication methods infront of budget with OIDC enabled - Using Desktop Browsers as the client, not any desktop app or form of that - I do SSO/IAM related stuff, so I am fairly confident that this is setup correctly, the only thing currently missing which I believe is in the plans is the Single Logout / Logout entry point. - Only way to resolve the above is clear cookies and cache for the site (on a subdomain).
Author
Owner

@dr3nch commented on GitHub (Apr 18, 2025):

Setting up openID with the available Docker image (actualbudget/actual-server:latest, Debian-based 25.4.0) in an environment with a local CA is a bit finicky right now.

Usually, it's enough to bind-mount a CA certificate into the container to make it trust a local CA:

/path/to/my_ca.crt:/usr/local/share/ca-certificates/my_ca.crt

Apparently, the latest and edge versions of this image don't have ca-certificates and curl pre-installed, despite being recommended by the official docs https://actualbudget.org/docs/install/docker/

Without ca-certificates, additional CAs will not install automatically, and the only way to install them is to inject the package manually:

command:
  - /bin/sh
  - -c
  - |
    apt update && apt install curl ca-certificates -y
    node app.js

Node.js doesn't trust the system store by default and will output errors like unable to verify the first certificate and UNABLE_TO_VERIFY_LEAF_SIGNATURE on every openID activation attempt. Even with a correctly installed CA, Node.js must be forced to trust it using environment variables:

- NODE_OPTIONS="--use-openssl-ca"
- SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt

I think at least some of this should be, if not fixed, then included into the docs.

@dr3nch commented on GitHub (Apr 18, 2025): Setting up openID with the available Docker image (actualbudget/actual-server:latest, Debian-based 25.4.0) in an environment with a local CA is a bit finicky right now. Usually, it's enough to bind-mount a CA certificate into the container to make it trust a local CA: ```docker-compose /path/to/my_ca.crt:/usr/local/share/ca-certificates/my_ca.crt ``` Apparently, the `latest` and `edge` versions of this image don't have `ca-certificates` and `curl` pre-installed, despite being recommended by the official docs https://actualbudget.org/docs/install/docker/ Without `ca-certificates`, additional CAs will not install automatically, and the only way to install them is to inject the package manually: ```docker-compose command: - /bin/sh - -c - | apt update && apt install curl ca-certificates -y node app.js ``` Node.js doesn't trust the system store by default and will output errors like `unable to verify the first certificate` and `UNABLE_TO_VERIFY_LEAF_SIGNATURE` on every openID activation attempt. Even with a correctly installed CA, Node.js must be forced to trust it using environment variables: ``` - NODE_OPTIONS="--use-openssl-ca" - SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt ``` I think at least some of this should be, if not fixed, then included into the docs.
Author
Owner

@vanchaxy commented on GitHub (Apr 25, 2025):

How can I get it working with PWA on Android/Chrome? When the app is installed, I'm forwarded to the app after the login with this error: {"status":"error","reason":"openid-grant-failed"}

Pixel 7, Android 16, Chrome 135, Actual v25.4.0, Pocket ID v0.45.0

Pocked ID logs:

[GIN] 2025/04/25 - 18:46:15 | 400 |   70.444841ms |    10.244.0.224 | POST     "/api/oidc/token"
Error #01: invalid authorization code
[GIN] 2025/04/25 - 18:46:15 | 400 |    70.47651ms |    10.244.0.224 | POST     "/api/oidc/token"
Error #01: invalid authorization code

Actual logs:

Logging in via openid
2025-04-25T18:46:13.487Z info: POST 200 /account/login
Deleted 0 old sessions
2025-04-25T18:46:15.250Z info: GET 302 /openid/callback?code=XEFAeIznA0vOB41SlcYuDezaVk70fmOE&state=XNanRUgDOXLGwPK8_QoWq9_MUaIt11jKj46iM-nJc6s
OpenID grant failed: OPError: Invalid authorization code
    at processResponse (/app/node_modules/openid-client/lib/helpers/process_response.js:38:13)
    at Client.grant (/app/node_modules/openid-client/lib/client.js:1381:22)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Client.callback (/app/node_modules/openid-client/lib/client.js:520:24)
    at async loginWithOpenIdFinalize (file:///app/src/accounts/openid.js:185:18)
    at async file:///app/src/app-openid.js:87:26 {
  error: 'Invalid authorization code'
}
2025-04-25T18:46:15.450Z info: GET 400 /openid/callback?code=XEFAeIznA0vOB41SlcYuDezaVk70fmOE&state=XNanRUgDOXLGwPK8_QoWq9_MUaIt11jKj46iM-nJc6s

It works if I request desktop mode, log in, and then open PWA. But then the session randomly expired, and I need to log in again. At the same time, everything works fine on the desktop version.

@vanchaxy commented on GitHub (Apr 25, 2025): How can I get it working with PWA on Android/Chrome? When the app is installed, I'm forwarded to the app after the login with this error: `{"status":"error","reason":"openid-grant-failed"}` Pixel 7, Android 16, Chrome 135, Actual v25.4.0, Pocket ID v0.45.0 Pocked ID logs: ``` [GIN] 2025/04/25 - 18:46:15 | 400 | 70.444841ms | 10.244.0.224 | POST "/api/oidc/token" Error #01: invalid authorization code [GIN] 2025/04/25 - 18:46:15 | 400 | 70.47651ms | 10.244.0.224 | POST "/api/oidc/token" Error #01: invalid authorization code ``` Actual logs: ``` Logging in via openid 2025-04-25T18:46:13.487Z info: POST 200 /account/login Deleted 0 old sessions 2025-04-25T18:46:15.250Z info: GET 302 /openid/callback?code=XEFAeIznA0vOB41SlcYuDezaVk70fmOE&state=XNanRUgDOXLGwPK8_QoWq9_MUaIt11jKj46iM-nJc6s OpenID grant failed: OPError: Invalid authorization code at processResponse (/app/node_modules/openid-client/lib/helpers/process_response.js:38:13) at Client.grant (/app/node_modules/openid-client/lib/client.js:1381:22) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async Client.callback (/app/node_modules/openid-client/lib/client.js:520:24) at async loginWithOpenIdFinalize (file:///app/src/accounts/openid.js:185:18) at async file:///app/src/app-openid.js:87:26 { error: 'Invalid authorization code' } 2025-04-25T18:46:15.450Z info: GET 400 /openid/callback?code=XEFAeIznA0vOB41SlcYuDezaVk70fmOE&state=XNanRUgDOXLGwPK8_QoWq9_MUaIt11jKj46iM-nJc6s ``` It works if I request desktop mode, log in, and then open PWA. But then the session randomly expired, and I need to log in again. At the same time, everything works fine on the desktop version.
Author
Owner

@MaxwellJP commented on GitHub (Apr 27, 2025):

Is it intentional that Multi-User OpenID shares Simplefin across all users/budgets? I have OpenID successfully setup with Authelia, as myself and other users can all log in and authenticate with OpenID, but anybody can link bank accounts to a single users SimpleFin account.

I'd like to share my Budget instance with multiple people, but only allowing a single person to link SimpleFin accounts makes it a bit unusable.

@MaxwellJP commented on GitHub (Apr 27, 2025): Is it intentional that Multi-User OpenID shares Simplefin across all users/budgets? I have OpenID successfully setup with Authelia, as myself and other users can all log in and authenticate with OpenID, but anybody can link bank accounts to a single users SimpleFin account. I'd like to share my Budget instance with multiple people, but only allowing a single person to link SimpleFin accounts makes it a bit unusable.
Author
Owner

@Cilenco commented on GitHub (Apr 29, 2025):

I'm using docker to host my own server but for the love of god I cannot setup OIDC via env variables or the config file. I tried:

{
  "loginMethod": "openid",
  "allowedLoginMethods": ["openid"],
  "openId": {
    "discoveryURL": "https://auth.domain.tld",
    "client_id": "budget",
    "client_secret": "...",
    "server_hostname": "https://budget.domain.tld",
    "authMethod": "oauth2"
  }
}

This file is mounted as config.json under the /data directory in the container but when I startup the container I have to setup a password and then setup OIDC via the UI. After configuring OIDC through the UI the login works perfectly well so it's not a problem with the auth provider (Authelia btw). From the logs I can see that the loginMethod and allowdLoginMethods are correctly pulled from the config but the openId section seems to not be recognized. I also tried using env variables but with the same result.

Server version is 25.4.0 so the enable-openid option is no longer valid.

EDIT: Switch to the latest edge tag, everything works fine now :)
P.S: env ACTUAL_USER_CREATION_MODE=login is a really nice addition to auto create users

@Cilenco commented on GitHub (Apr 29, 2025): I'm using docker to host my own server but for the love of god I cannot setup OIDC via env variables or the config file. I tried: ``` { "loginMethod": "openid", "allowedLoginMethods": ["openid"], "openId": { "discoveryURL": "https://auth.domain.tld", "client_id": "budget", "client_secret": "...", "server_hostname": "https://budget.domain.tld", "authMethod": "oauth2" } } ``` This file is mounted as `config.json` under the `/data` directory in the container but when I startup the container I have to setup a password and then setup OIDC via the UI. After configuring OIDC through the UI the login works perfectly well so it's not a problem with the auth provider (Authelia btw). From the logs I can see that the `loginMethod` and `allowdLoginMethods` are correctly pulled from the config but the `openId` section seems to not be recognized. I also tried using env variables but with the same result. Server version is 25.4.0 so the `enable-openid` option is no longer valid. **EDIT:** Switch to the latest edge tag, everything works fine now :) P.S: env ACTUAL_USER_CREATION_MODE=login is a really nice addition to auto create users
Author
Owner

@lelemm commented on GitHub (Apr 30, 2025):

Is it intentional that Multi-User OpenID shares Simplefin across all users/budgets? I have OpenID successfully setup with Authelia, as myself and other users can all log in and authenticate with OpenID, but anybody can link bank accounts to a single users SimpleFin account.

I'd like to share my Budget instance with multiple people, but only allowing a single person to link SimpleFin accounts makes it a bit unusable.

Bank credentials are a separate feature of a multi-user system. They don't depend on the logged user (and shouldn't).
To support what you need, it would require implementing bank credentials per budget file, not per user.
Some users want that, but no one has implemented it yet.

@lelemm commented on GitHub (Apr 30, 2025): > Is it intentional that Multi-User OpenID shares Simplefin across all users/budgets? I have OpenID successfully setup with Authelia, as myself and other users can all log in and authenticate with OpenID, but anybody can link bank accounts to a single users SimpleFin account. > > I'd like to share my Budget instance with multiple people, but only allowing a single person to link SimpleFin accounts makes it a bit unusable. Bank credentials are a separate feature of a multi-user system. They don't depend on the logged user (and shouldn't). To support what you need, it would require implementing bank credentials per budget file, not per user. Some users want that, but no one has implemented it yet.
Author
Owner

@lelemm commented on GitHub (Apr 30, 2025):

How can I get it working with PWA on Android/Chrome? When the app is installed, I'm forwarded to the app after the login with this error: {"status":"error","reason":"openid-grant-failed"}

Pixel 7, Android 16, Chrome 135, Actual v25.4.0, Pocket ID v0.45.0

Pocked ID logs:

[GIN] 2025/04/25 - 18:46:15 | 400 |   70.444841ms |    10.244.0.224 | POST     "/api/oidc/token"
Error #01: invalid authorization code
[GIN] 2025/04/25 - 18:46:15 | 400 |    70.47651ms |    10.244.0.224 | POST     "/api/oidc/token"
Error #01: invalid authorization code

Actual logs:

Logging in via openid
2025-04-25T18:46:13.487Z info: POST 200 /account/login
Deleted 0 old sessions
2025-04-25T18:46:15.250Z info: GET 302 /openid/callback?code=XEFAeIznA0vOB41SlcYuDezaVk70fmOE&state=XNanRUgDOXLGwPK8_QoWq9_MUaIt11jKj46iM-nJc6s
OpenID grant failed: OPError: Invalid authorization code
    at processResponse (/app/node_modules/openid-client/lib/helpers/process_response.js:38:13)
    at Client.grant (/app/node_modules/openid-client/lib/client.js:1381:22)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Client.callback (/app/node_modules/openid-client/lib/client.js:520:24)
    at async loginWithOpenIdFinalize (file:///app/src/accounts/openid.js:185:18)
    at async file:///app/src/app-openid.js:87:26 {
  error: 'Invalid authorization code'
}
2025-04-25T18:46:15.450Z info: GET 400 /openid/callback?code=XEFAeIznA0vOB41SlcYuDezaVk70fmOE&state=XNanRUgDOXLGwPK8_QoWq9_MUaIt11jKj46iM-nJc6s

It works if I request desktop mode, log in, and then open PWA. But then the session randomly expired, and I need to log in again. At the same time, everything works fine on the desktop version.

My PWA credentials "migrated" from the browser into the PWA.
I didn't have to login again

@lelemm commented on GitHub (Apr 30, 2025): > How can I get it working with PWA on Android/Chrome? When the app is installed, I'm forwarded to the app after the login with this error: `{"status":"error","reason":"openid-grant-failed"}` > > Pixel 7, Android 16, Chrome 135, Actual v25.4.0, Pocket ID v0.45.0 > > Pocked ID logs: > > ``` > [GIN] 2025/04/25 - 18:46:15 | 400 | 70.444841ms | 10.244.0.224 | POST "/api/oidc/token" > Error #01: invalid authorization code > [GIN] 2025/04/25 - 18:46:15 | 400 | 70.47651ms | 10.244.0.224 | POST "/api/oidc/token" > Error #01: invalid authorization code > ``` > > Actual logs: > > ``` > Logging in via openid > 2025-04-25T18:46:13.487Z info: POST 200 /account/login > Deleted 0 old sessions > 2025-04-25T18:46:15.250Z info: GET 302 /openid/callback?code=XEFAeIznA0vOB41SlcYuDezaVk70fmOE&state=XNanRUgDOXLGwPK8_QoWq9_MUaIt11jKj46iM-nJc6s > OpenID grant failed: OPError: Invalid authorization code > at processResponse (/app/node_modules/openid-client/lib/helpers/process_response.js:38:13) > at Client.grant (/app/node_modules/openid-client/lib/client.js:1381:22) > at process.processTicksAndRejections (node:internal/process/task_queues:95:5) > at async Client.callback (/app/node_modules/openid-client/lib/client.js:520:24) > at async loginWithOpenIdFinalize (file:///app/src/accounts/openid.js:185:18) > at async file:///app/src/app-openid.js:87:26 { > error: 'Invalid authorization code' > } > 2025-04-25T18:46:15.450Z info: GET 400 /openid/callback?code=XEFAeIznA0vOB41SlcYuDezaVk70fmOE&state=XNanRUgDOXLGwPK8_QoWq9_MUaIt11jKj46iM-nJc6s > ``` > > It works if I request desktop mode, log in, and then open PWA. But then the session randomly expired, and I need to log in again. At the same time, everything works fine on the desktop version. My PWA credentials "migrated" from the browser into the PWA. I didn't have to login again
Author
Owner

@MaxwellJP commented on GitHub (Apr 30, 2025):

Is it intentional that Multi-User OpenID shares Simplefin across all users/budgets? I have OpenID successfully setup with Authelia, as myself and other users can all log in and authenticate with OpenID, but anybody can link bank accounts to a single users SimpleFin account.
I'd like to share my Budget instance with multiple people, but only allowing a single person to link SimpleFin accounts makes it a bit unusable.

Bank credentials are a separate feature of a multi-user system. They don't depend on the logged user (and shouldn't). To support what you need, it would require implementing bank credentials per budget file, not per user. Some users want that, but no one has implemented it yet.

That makes sense, bank credentials per budget file would be fine. I guess I misunderstood your comment on Feb. 06:

Fix SimpleFin token sharing issue for multi-user environments.

My question would be, what is the purpose of a muti-user system if only a single user can use bank-sync? As always, many thanks for both the contributions and commentary :)

@MaxwellJP commented on GitHub (Apr 30, 2025): > > Is it intentional that Multi-User OpenID shares Simplefin across all users/budgets? I have OpenID successfully setup with Authelia, as myself and other users can all log in and authenticate with OpenID, but anybody can link bank accounts to a single users SimpleFin account. > > I'd like to share my Budget instance with multiple people, but only allowing a single person to link SimpleFin accounts makes it a bit unusable. > > Bank credentials are a separate feature of a multi-user system. They don't depend on the logged user (and shouldn't). To support what you need, it would require implementing bank credentials per budget file, not per user. Some users want that, but no one has implemented it yet. That makes sense, bank credentials per budget file would be fine. I guess I misunderstood your comment on Feb. 06: > ⏳ Fix SimpleFin token sharing issue for multi-user environments. My question would be, what is the purpose of a muti-user system if only a single user can use bank-sync? As always, many thanks for both the contributions and commentary :)
Author
Owner

@lelemm commented on GitHub (Apr 30, 2025):

Is it intentional that Multi-User OpenID shares Simplefin across all users/budgets? I have OpenID successfully setup with Authelia, as myself and other users can all log in and authenticate with OpenID, but anybody can link bank accounts to a single users SimpleFin account.
I'd like to share my Budget instance with multiple people, but only allowing a single person to link SimpleFin accounts makes it a bit unusable.

Bank credentials are a separate feature of a multi-user system. They don't depend on the logged user (and shouldn't). To support what you need, it would require implementing bank credentials per budget file, not per user. Some users want that, but no one has implemented it yet.

That makes sense, bank credentials per budget file would be fine. I guess I misunderstood your comment on Feb. 06:

Fix SimpleFin token sharing issue for multi-user environments.

My question would be, what is the purpose of a muti-user system if only a single user can use bank-sync? As always, many thanks for both the contributions and commentary :)

This is for families/friends that don't mind sharing the same bank sync account or not using one.
Actual is not ready for SAAS usage.

@lelemm commented on GitHub (Apr 30, 2025): > > > Is it intentional that Multi-User OpenID shares Simplefin across all users/budgets? I have OpenID successfully setup with Authelia, as myself and other users can all log in and authenticate with OpenID, but anybody can link bank accounts to a single users SimpleFin account. > > > I'd like to share my Budget instance with multiple people, but only allowing a single person to link SimpleFin accounts makes it a bit unusable. > > > > > > Bank credentials are a separate feature of a multi-user system. They don't depend on the logged user (and shouldn't). To support what you need, it would require implementing bank credentials per budget file, not per user. Some users want that, but no one has implemented it yet. > > That makes sense, bank credentials per budget file would be fine. I guess I misunderstood your comment on Feb. 06: > > > ⏳ Fix SimpleFin token sharing issue for multi-user environments. > > My question would be, what is the purpose of a muti-user system if only a single user can use bank-sync? As always, many thanks for both the contributions and commentary :) This is for families/friends that don't mind sharing the same bank sync account or not using one. Actual is not ready for SAAS usage.
Author
Owner

@MaxwellJP commented on GitHub (Apr 30, 2025):

That makes sense, bank credentials per budget file would be fine. I guess I misunderstood your comment on Feb. 06:

Fix SimpleFin token sharing issue for multi-user environments.

My question would be, what is the purpose of a muti-user system if only a single user can use bank-sync? As always, many thanks for both the contributions and commentary :)

This is for families/friends that don't mind sharing the same bank sync account or not using one. Actual is not ready for SAAS usage.

Apologies! I did not mean to suggest that it would be used with people outside of my direct family and close friends.

To clarify my specific scenario, I have myself, a direct family member, and a life-long friend I was hoping to share Actual with. Although both of these people are incredibly close to me, I didn't think it made sense for my friend to see the family members financials (and vice versa). They also both want to utilize bank sync.

Currently, my workaround is running multiple instances of Actual which seems to defeat the purpose of a multi-user system. Of course, this is just my opinion as I'm not a contributor, just wanted to share my thoughts (I hope this comes across in the right way). Not to belabor the topic, but could you please clarify the plan/vision for the multi-user system?

Thanks again!

@MaxwellJP commented on GitHub (Apr 30, 2025): > > That makes sense, bank credentials per budget file would be fine. I guess I misunderstood your comment on Feb. 06: > > > ⏳ Fix SimpleFin token sharing issue for multi-user environments. > > > > > > My question would be, what is the purpose of a muti-user system if only a single user can use bank-sync? As always, many thanks for both the contributions and commentary :) > > This is for families/friends that don't mind sharing the same bank sync account or not using one. Actual is not ready for SAAS usage. Apologies! I did not mean to suggest that it would be used with people outside of my direct family and close friends. To clarify my specific scenario, I have myself, a direct family member, and a life-long friend I was hoping to share Actual with. Although both of these people are incredibly close to me, I didn't think it made sense for my friend to see the family members financials (and vice versa). They also both want to utilize bank sync. Currently, my workaround is running multiple instances of Actual which seems to defeat the purpose of a multi-user system. Of course, this is just my opinion as I'm not a contributor, just wanted to share my thoughts (I hope this comes across in the right way). Not to belabor the topic, but could you please clarify the plan/vision for the multi-user system? Thanks again!
Author
Owner

@darthkali commented on GitHub (May 1, 2025):

Hello,
I have successfully set up Actual with OpenID and Keycloak. However, I'm facing an issue with logging out:
when I sign out of Actual, the Keycloak session remains active, so I'm automatically logged back in without being prompted.

Is there a configuration in either Keycloak or Actual to ensure that the Keycloak session is properly terminated during logout?

Thank you in advance!

@darthkali commented on GitHub (May 1, 2025): Hello, I have successfully set up Actual with OpenID and Keycloak. However, I'm facing an issue with logging out: when I sign out of Actual, the Keycloak session remains active, so I'm automatically logged back in without being prompted. Is there a configuration in either Keycloak or Actual to ensure that the Keycloak session is properly terminated during logout? Thank you in advance!
Author
Owner

@lelemm commented on GitHub (May 2, 2025):

Hello, I have successfully set up Actual with OpenID and Keycloak. However, I'm facing an issue with logging out: when I sign out of Actual, the Keycloak session remains active, so I'm automatically logged back in without being prompted.

Is there a configuration in either Keycloak or Actual to ensure that the Keycloak session is properly terminated during logout?

Thank you in advance!

There is a PR on the way for this. Still missing the desktop client support for it.

@lelemm commented on GitHub (May 2, 2025): > Hello, I have successfully set up Actual with OpenID and Keycloak. However, I'm facing an issue with logging out: when I sign out of Actual, the Keycloak session remains active, so I'm automatically logged back in without being prompted. > > Is there a configuration in either Keycloak or Actual to ensure that the Keycloak session is properly terminated during logout? > > Thank you in advance! There is a PR on the way for this. Still missing the desktop client support for it.
Author
Owner

@guspimentel commented on GitHub (May 2, 2025):

I'm new to Actual, but allow me to support @MaxwellJP's suggestion.

I have myself, a direct family member, and a life-long friend I was hoping to share Actual with.

I also have a close friend hoping we could share the same Actual server, but have separate budgets and users in isolation. The main reason is that we both could help each other to setup the environment and extend the application to our need. But I understand that adding this feature would be a giant step to turn Actual into a SaaS, and I don't know if this is the maintainers intention.

@guspimentel commented on GitHub (May 2, 2025): I'm new to Actual, but allow me to support @MaxwellJP's suggestion. > I have myself, a direct family member, and a life-long friend I was hoping to share Actual with. I also have a close friend hoping we could share the same Actual server, but have separate budgets and users in isolation. The main reason is that we both could help each other to setup the environment and extend the application to our need. But I understand that adding this feature would be a giant step to turn Actual into a SaaS, and I don't know if this is the maintainers intention.
Author
Owner

@dojoca commented on GitHub (May 6, 2025):

I've happily gotten this all set up nicely and it's working well.
My main aim was to have 2FA using authentik.
However, i still see a "Select the login method", which allows me to sign in with a password. Is there a way to disable this option? I only want OpenID to be usable, as if a person can just choose to log in with a password then the 2FA is not useful.

@dojoca commented on GitHub (May 6, 2025): I've happily gotten this all set up nicely and it's working well. My main aim was to have 2FA using authentik. However, i still see a "Select the login method", which allows me to sign in with a password. Is there a way to disable this option? I only want OpenID to be usable, as if a person can just choose to log in with a password then the 2FA is not useful.
Author
Owner

@ajf15cc commented on GitHub (May 6, 2025):

I've happily gotten this all set up nicely and it's working well. My main aim was to have 2FA using authentik. However, i still see a "Select the login method", which allows me to sign in with a password. Is there a way to disable this option? I only want OpenID to be usable, as if a person can just choose to log in with a password then the 2FA is not useful.

If you add the env variable ACTUAL_OPENID_ENFORCE=true that should force OIDC always.

@ajf15cc commented on GitHub (May 6, 2025): > I've happily gotten this all set up nicely and it's working well. My main aim was to have 2FA using authentik. However, i still see a "Select the login method", which allows me to sign in with a password. Is there a way to disable this option? I only want OpenID to be usable, as if a person can just choose to log in with a password then the 2FA is not useful. If you add the env variable ACTUAL_OPENID_ENFORCE=true that should force OIDC always.
Author
Owner

@dojoca commented on GitHub (May 6, 2025):

I've happily gotten this all set up nicely and it's working well. My main aim was to have 2FA using authentik. However, i still see a "Select the login method", which allows me to sign in with a password. Is there a way to disable this option? I only want OpenID to be usable, as if a person can just choose to log in with a password then the 2FA is not useful.

If you add the env variable ACTUAL_OPENID_ENFORCE=true that should force OIDC always.

You are an absolute star. Thank you so much!

@dojoca commented on GitHub (May 6, 2025): > > I've happily gotten this all set up nicely and it's working well. My main aim was to have 2FA using authentik. However, i still see a "Select the login method", which allows me to sign in with a password. Is there a way to disable this option? I only want OpenID to be usable, as if a person can just choose to log in with a password then the 2FA is not useful. > > > If you add the env variable ACTUAL_OPENID_ENFORCE=true that should force OIDC always. > > You are an absolute star. Thank you so much!
Author
Owner

@ParametricToroid commented on GitHub (May 8, 2025):

Hello everyone, I've been trying to implement multi-user via OpenID, though Authelia, and have had limited success. I chose to build from source, and have been trying to leverage config.json for the authentication parameters for Authelia.

After providing the server password, Actual Budget sends me to Authelia to authenticate, and back to Actual Budget, however I get the following error (that I've seen a few times here):

{"status":"error","reason":"openid-grant-failed"}

For reference my config.json looks like:

  "loginMethod": "openid",
  "allowedLoginMethods": ["openid"],
  "openId": {
    "discoveryURL": "https://auth.<my_domain>.com",
    "client_id": "<client_id>",
    "client_secret": "<client_secret>",
    "server_hostname": "https://actual-budget.<my_domain>.com",
    "authMethod": "oauth2"
  }
}

The log from Actual Budget:

2025-05-08T01:54:42.801Z info: GET 304 /account/needs-bootstrap
2025-05-08T01:54:42.830Z info: GET 304 /account/needs-bootstrap
2025-05-08T01:54:42.864Z info: GET 304 /account/needs-bootstrap
2025-05-08T01:54:42.879Z info: GET 304 /admin/owner-created/
Logging in via openid
2025-05-08T01:54:46.383Z info: POST 200 /account/login
OpenID grant failed: OPError: invalid_client (Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method).)
     at processResponse (/opt/actual/actual/node_modules/openid-client/lib/helpers/process_response.js:38:13)
     at Client.grant (/opt/actual/actual/node_modules/openid-client/lib/client.js:1381:22)
     at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
     at async loginWithOpenIdFinalize (file:///opt/actual/actual/packages/sync-server/src/accounts/openid.js:215:18)
     at async file:///opt/actual/actual/packages/sync-server/src/app-openid.js:93:26 {
   error: 'invalid_client',
   error_description: 'Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method).'
 }
2025-05-08T01:54:47.521Z info: GET 400 /openid/callback?code=authelia_ac_HRTN_2GMK4RlAyC-khGJA0BZcOo1LiK47F4jZIcIDFk.qy6C7NsBfsg7-W4Sc2FMgOQ_ujX0Nk6Ipe64wNkB1pI&iss=https%3A%2F%2Fauth.<my_domain>.com&scope=openid+email+profile&state=8ynOYy7hOj8Yt5PWLZX9eqYRvMu8RHzBZZhLr4_Qk3M

This is a snippet of my configuration.yml from Authelia:

identity_providers:
  oidc:
    clients:
      - client_id: "<client_id>"  # read above for how generate
        client_name: "Actual Budget" # will be displayed in Authelia to users
        client_secret: "<client_secret>" # read above for how generate
        public: false
        authorization_policy: "one_factor" # or one_factor, depending on your needs
        redirect_uris:
          - "https://actual-budget.<my_domain>.com/openid/callback"
        scopes:
          - "openid"
          - "profile"
          - "groups"
          - "email"
        userinfo_signed_response_alg: "none"
        token_endpoint_auth_method: "client_secret_basic"

I'm copying the client_id and client_secret directly from Authelia, so I don't imagine it is an issue of the actual credential's mismatching.
Anyone have any ideas? Thanks in advance!

@ParametricToroid commented on GitHub (May 8, 2025): Hello everyone, I've been trying to implement multi-user via OpenID, though Authelia, and have had limited success. I chose to build from source, and have been trying to leverage config.json for the authentication parameters for Authelia. After providing the server password, Actual Budget sends me to Authelia to authenticate, and back to Actual Budget, however I get the following error (that I've seen a few times here): ``` {"status":"error","reason":"openid-grant-failed"} ``` For reference my `config.json` looks like: ```{ "loginMethod": "openid", "allowedLoginMethods": ["openid"], "openId": { "discoveryURL": "https://auth.<my_domain>.com", "client_id": "<client_id>", "client_secret": "<client_secret>", "server_hostname": "https://actual-budget.<my_domain>.com", "authMethod": "oauth2" } } ``` The log from Actual Budget: ``` 2025-05-08T01:54:42.801Z info: GET 304 /account/needs-bootstrap 2025-05-08T01:54:42.830Z info: GET 304 /account/needs-bootstrap 2025-05-08T01:54:42.864Z info: GET 304 /account/needs-bootstrap 2025-05-08T01:54:42.879Z info: GET 304 /admin/owner-created/ Logging in via openid 2025-05-08T01:54:46.383Z info: POST 200 /account/login OpenID grant failed: OPError: invalid_client (Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method).) at processResponse (/opt/actual/actual/node_modules/openid-client/lib/helpers/process_response.js:38:13) at Client.grant (/opt/actual/actual/node_modules/openid-client/lib/client.js:1381:22) at process.processTicksAndRejections (node:internal/process/task_queues:105:5) at async loginWithOpenIdFinalize (file:///opt/actual/actual/packages/sync-server/src/accounts/openid.js:215:18) at async file:///opt/actual/actual/packages/sync-server/src/app-openid.js:93:26 { error: 'invalid_client', error_description: 'Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method).' } 2025-05-08T01:54:47.521Z info: GET 400 /openid/callback?code=authelia_ac_HRTN_2GMK4RlAyC-khGJA0BZcOo1LiK47F4jZIcIDFk.qy6C7NsBfsg7-W4Sc2FMgOQ_ujX0Nk6Ipe64wNkB1pI&iss=https%3A%2F%2Fauth.<my_domain>.com&scope=openid+email+profile&state=8ynOYy7hOj8Yt5PWLZX9eqYRvMu8RHzBZZhLr4_Qk3M ``` This is a snippet of my `configuration.yml` from Authelia: ``` identity_providers: oidc: clients: - client_id: "<client_id>" # read above for how generate client_name: "Actual Budget" # will be displayed in Authelia to users client_secret: "<client_secret>" # read above for how generate public: false authorization_policy: "one_factor" # or one_factor, depending on your needs redirect_uris: - "https://actual-budget.<my_domain>.com/openid/callback" scopes: - "openid" - "profile" - "groups" - "email" userinfo_signed_response_alg: "none" token_endpoint_auth_method: "client_secret_basic" ``` I'm copying the client_id and client_secret directly from Authelia, so I don't imagine it is an issue of the actual credential's mismatching. Anyone have any ideas? Thanks in advance!
Author
Owner

@lelemm commented on GitHub (May 8, 2025):

Hello everyone, I've been trying to implement multi-user via OpenID, though Authelia, and have had limited success. I chose to build from source, and have been trying to leverage config.json for the authentication parameters for Authelia.

After providing the server password, Actual Budget sends me to Authelia to authenticate, and back to Actual Budget, however I get the following error (that I've seen a few times here):

{"status":"error","reason":"openid-grant-failed"}

For reference my config.json looks like:

  "loginMethod": "openid",
  "allowedLoginMethods": ["openid"],
  "openId": {
    "discoveryURL": "https://auth.<my_domain>.com",
    "client_id": "<client_id>",
    "client_secret": "<client_secret>",
    "server_hostname": "https://actual-budget.<my_domain>.com",
    "authMethod": "oauth2"
  }
}

The log from Actual Budget:

2025-05-08T01:54:42.801Z info: GET 304 /account/needs-bootstrap
2025-05-08T01:54:42.830Z info: GET 304 /account/needs-bootstrap
2025-05-08T01:54:42.864Z info: GET 304 /account/needs-bootstrap
2025-05-08T01:54:42.879Z info: GET 304 /admin/owner-created/
Logging in via openid
2025-05-08T01:54:46.383Z info: POST 200 /account/login
OpenID grant failed: OPError: invalid_client (Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method).)
     at processResponse (/opt/actual/actual/node_modules/openid-client/lib/helpers/process_response.js:38:13)
     at Client.grant (/opt/actual/actual/node_modules/openid-client/lib/client.js:1381:22)
     at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
     at async loginWithOpenIdFinalize (file:///opt/actual/actual/packages/sync-server/src/accounts/openid.js:215:18)
     at async file:///opt/actual/actual/packages/sync-server/src/app-openid.js:93:26 {
   error: 'invalid_client',
   error_description: 'Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method).'
 }
2025-05-08T01:54:47.521Z info: GET 400 /openid/callback?code=authelia_ac_HRTN_2GMK4RlAyC-khGJA0BZcOo1LiK47F4jZIcIDFk.qy6C7NsBfsg7-W4Sc2FMgOQ_ujX0Nk6Ipe64wNkB1pI&iss=https%3A%2F%2Fauth.<my_domain>.com&scope=openid+email+profile&state=8ynOYy7hOj8Yt5PWLZX9eqYRvMu8RHzBZZhLr4_Qk3M

This is a snippet of my configuration.yml from Authelia:

identity_providers:
  oidc:
    clients:
      - client_id: "<client_id>"  # read above for how generate
        client_name: "Actual Budget" # will be displayed in Authelia to users
        client_secret: "<client_secret>" # read above for how generate
        public: false
        authorization_policy: "one_factor" # or one_factor, depending on your needs
        redirect_uris:
          - "https://actual-budget.<my_domain>.com/openid/callback"
        scopes:
          - "openid"
          - "profile"
          - "groups"
          - "email"
        userinfo_signed_response_alg: "none"
        token_endpoint_auth_method: "client_secret_basic"

I'm copying the client_id and client_secret directly from Authelia, so I don't imagine it is an issue of the actual credential's mismatching. Anyone have any ideas? Thanks in advance!

Any logs in Authelia?

@lelemm commented on GitHub (May 8, 2025): > Hello everyone, I've been trying to implement multi-user via OpenID, though Authelia, and have had limited success. I chose to build from source, and have been trying to leverage config.json for the authentication parameters for Authelia. > > After providing the server password, Actual Budget sends me to Authelia to authenticate, and back to Actual Budget, however I get the following error (that I've seen a few times here): > > ``` > {"status":"error","reason":"openid-grant-failed"} > ``` > > For reference my `config.json` looks like: > > ``` > "loginMethod": "openid", > "allowedLoginMethods": ["openid"], > "openId": { > "discoveryURL": "https://auth.<my_domain>.com", > "client_id": "<client_id>", > "client_secret": "<client_secret>", > "server_hostname": "https://actual-budget.<my_domain>.com", > "authMethod": "oauth2" > } > } > ``` > > The log from Actual Budget: > > ``` > 2025-05-08T01:54:42.801Z info: GET 304 /account/needs-bootstrap > 2025-05-08T01:54:42.830Z info: GET 304 /account/needs-bootstrap > 2025-05-08T01:54:42.864Z info: GET 304 /account/needs-bootstrap > 2025-05-08T01:54:42.879Z info: GET 304 /admin/owner-created/ > Logging in via openid > 2025-05-08T01:54:46.383Z info: POST 200 /account/login > OpenID grant failed: OPError: invalid_client (Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method).) > at processResponse (/opt/actual/actual/node_modules/openid-client/lib/helpers/process_response.js:38:13) > at Client.grant (/opt/actual/actual/node_modules/openid-client/lib/client.js:1381:22) > at process.processTicksAndRejections (node:internal/process/task_queues:105:5) > at async loginWithOpenIdFinalize (file:///opt/actual/actual/packages/sync-server/src/accounts/openid.js:215:18) > at async file:///opt/actual/actual/packages/sync-server/src/app-openid.js:93:26 { > error: 'invalid_client', > error_description: 'Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method).' > } > 2025-05-08T01:54:47.521Z info: GET 400 /openid/callback?code=authelia_ac_HRTN_2GMK4RlAyC-khGJA0BZcOo1LiK47F4jZIcIDFk.qy6C7NsBfsg7-W4Sc2FMgOQ_ujX0Nk6Ipe64wNkB1pI&iss=https%3A%2F%2Fauth.<my_domain>.com&scope=openid+email+profile&state=8ynOYy7hOj8Yt5PWLZX9eqYRvMu8RHzBZZhLr4_Qk3M > ``` > > This is a snippet of my `configuration.yml` from Authelia: > > ``` > identity_providers: > oidc: > clients: > - client_id: "<client_id>" # read above for how generate > client_name: "Actual Budget" # will be displayed in Authelia to users > client_secret: "<client_secret>" # read above for how generate > public: false > authorization_policy: "one_factor" # or one_factor, depending on your needs > redirect_uris: > - "https://actual-budget.<my_domain>.com/openid/callback" > scopes: > - "openid" > - "profile" > - "groups" > - "email" > userinfo_signed_response_alg: "none" > token_endpoint_auth_method: "client_secret_basic" > ``` > > I'm copying the client_id and client_secret directly from Authelia, so I don't imagine it is an issue of the actual credential's mismatching. Anyone have any ideas? Thanks in advance! Any logs in Authelia?
Author
Owner

@ParametricToroid commented on GitHub (May 8, 2025):

Hello everyone, I've been trying to implement multi-user via OpenID, though Authelia, and have had limited success. I chose to build from source, and have been trying to leverage config.json for the authentication parameters for Authelia.
After providing the server password, Actual Budget sends me to Authelia to authenticate, and back to Actual Budget, however I get the following error (that I've seen a few times here):

{"status":"error","reason":"openid-grant-failed"}

For reference my config.json looks like:

  "loginMethod": "openid",
  "allowedLoginMethods": ["openid"],
  "openId": {
    "discoveryURL": "https://auth.<my_domain>.com",
    "client_id": "<client_id>",
    "client_secret": "<client_secret>",
    "server_hostname": "https://actual-budget.<my_domain>.com",
    "authMethod": "oauth2"
  }
}

The log from Actual Budget:

2025-05-08T01:54:42.801Z info: GET 304 /account/needs-bootstrap
2025-05-08T01:54:42.830Z info: GET 304 /account/needs-bootstrap
2025-05-08T01:54:42.864Z info: GET 304 /account/needs-bootstrap
2025-05-08T01:54:42.879Z info: GET 304 /admin/owner-created/
Logging in via openid
2025-05-08T01:54:46.383Z info: POST 200 /account/login
OpenID grant failed: OPError: invalid_client (Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method).)
     at processResponse (/opt/actual/actual/node_modules/openid-client/lib/helpers/process_response.js:38:13)
     at Client.grant (/opt/actual/actual/node_modules/openid-client/lib/client.js:1381:22)
     at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
     at async loginWithOpenIdFinalize (file:///opt/actual/actual/packages/sync-server/src/accounts/openid.js:215:18)
     at async file:///opt/actual/actual/packages/sync-server/src/app-openid.js:93:26 {
   error: 'invalid_client',
   error_description: 'Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method).'
 }
2025-05-08T01:54:47.521Z info: GET 400 /openid/callback?code=authelia_ac_HRTN_2GMK4RlAyC-khGJA0BZcOo1LiK47F4jZIcIDFk.qy6C7NsBfsg7-W4Sc2FMgOQ_ujX0Nk6Ipe64wNkB1pI&iss=https%3A%2F%2Fauth.<my_domain>.com&scope=openid+email+profile&state=8ynOYy7hOj8Yt5PWLZX9eqYRvMu8RHzBZZhLr4_Qk3M

This is a snippet of my configuration.yml from Authelia:

identity_providers:
  oidc:
    clients:
      - client_id: "<client_id>"  # read above for how generate
        client_name: "Actual Budget" # will be displayed in Authelia to users
        client_secret: "<client_secret>" # read above for how generate
        public: false
        authorization_policy: "one_factor" # or one_factor, depending on your needs
        redirect_uris:
          - "https://actual-budget.<my_domain>.com/openid/callback"
        scopes:
          - "openid"
          - "profile"
          - "groups"
          - "email"
        userinfo_signed_response_alg: "none"
        token_endpoint_auth_method: "client_secret_basic"

I'm copying the client_id and client_secret directly from Authelia, so I don't imagine it is an issue of the actual credential's mismatching. Anyone have any ideas? Thanks in advance!

Any logs in Authelia?

Thanks for the reply!
Yes, this is the log entry for the authentication attempt:

May 08 09:28:54 authelia authelia[385]: time="2025-05-08T09:28:54-04:00" level=error msg="Access Request failed with error: Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method). The provided client secret did not match the registered client secret." method=POST path=/api/oidc/token remote_ip=10.10.20.58

The client_secrets match exactly, so perhaps there is a configuration issue with Actual Budget pulling my config.json?

@ParametricToroid commented on GitHub (May 8, 2025): > > Hello everyone, I've been trying to implement multi-user via OpenID, though Authelia, and have had limited success. I chose to build from source, and have been trying to leverage config.json for the authentication parameters for Authelia. > > After providing the server password, Actual Budget sends me to Authelia to authenticate, and back to Actual Budget, however I get the following error (that I've seen a few times here): > > ``` > > {"status":"error","reason":"openid-grant-failed"} > > ``` > > > > > > > > > > > > > > > > > > > > > > > > For reference my `config.json` looks like: > > ``` > > "loginMethod": "openid", > > "allowedLoginMethods": ["openid"], > > "openId": { > > "discoveryURL": "https://auth.<my_domain>.com", > > "client_id": "<client_id>", > > "client_secret": "<client_secret>", > > "server_hostname": "https://actual-budget.<my_domain>.com", > > "authMethod": "oauth2" > > } > > } > > ``` > > > > > > > > > > > > > > > > > > > > > > > > The log from Actual Budget: > > ``` > > 2025-05-08T01:54:42.801Z info: GET 304 /account/needs-bootstrap > > 2025-05-08T01:54:42.830Z info: GET 304 /account/needs-bootstrap > > 2025-05-08T01:54:42.864Z info: GET 304 /account/needs-bootstrap > > 2025-05-08T01:54:42.879Z info: GET 304 /admin/owner-created/ > > Logging in via openid > > 2025-05-08T01:54:46.383Z info: POST 200 /account/login > > OpenID grant failed: OPError: invalid_client (Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method).) > > at processResponse (/opt/actual/actual/node_modules/openid-client/lib/helpers/process_response.js:38:13) > > at Client.grant (/opt/actual/actual/node_modules/openid-client/lib/client.js:1381:22) > > at process.processTicksAndRejections (node:internal/process/task_queues:105:5) > > at async loginWithOpenIdFinalize (file:///opt/actual/actual/packages/sync-server/src/accounts/openid.js:215:18) > > at async file:///opt/actual/actual/packages/sync-server/src/app-openid.js:93:26 { > > error: 'invalid_client', > > error_description: 'Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method).' > > } > > 2025-05-08T01:54:47.521Z info: GET 400 /openid/callback?code=authelia_ac_HRTN_2GMK4RlAyC-khGJA0BZcOo1LiK47F4jZIcIDFk.qy6C7NsBfsg7-W4Sc2FMgOQ_ujX0Nk6Ipe64wNkB1pI&iss=https%3A%2F%2Fauth.<my_domain>.com&scope=openid+email+profile&state=8ynOYy7hOj8Yt5PWLZX9eqYRvMu8RHzBZZhLr4_Qk3M > > ``` > > > > > > > > > > > > > > > > > > > > > > > > This is a snippet of my `configuration.yml` from Authelia: > > ``` > > identity_providers: > > oidc: > > clients: > > - client_id: "<client_id>" # read above for how generate > > client_name: "Actual Budget" # will be displayed in Authelia to users > > client_secret: "<client_secret>" # read above for how generate > > public: false > > authorization_policy: "one_factor" # or one_factor, depending on your needs > > redirect_uris: > > - "https://actual-budget.<my_domain>.com/openid/callback" > > scopes: > > - "openid" > > - "profile" > > - "groups" > > - "email" > > userinfo_signed_response_alg: "none" > > token_endpoint_auth_method: "client_secret_basic" > > ``` > > > > > > > > > > > > > > > > > > > > > > > > I'm copying the client_id and client_secret directly from Authelia, so I don't imagine it is an issue of the actual credential's mismatching. Anyone have any ideas? Thanks in advance! > > Any logs in Authelia? Thanks for the reply! Yes, this is the log entry for the authentication attempt: ``` May 08 09:28:54 authelia authelia[385]: time="2025-05-08T09:28:54-04:00" level=error msg="Access Request failed with error: Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method). The provided client secret did not match the registered client secret." method=POST path=/api/oidc/token remote_ip=10.10.20.58 ``` The client_secrets match exactly, so perhaps there is a configuration issue with Actual Budget pulling my `config.json`?
Author
Owner

@lelemm commented on GitHub (May 8, 2025):

Hello everyone, I've been trying to implement multi-user via OpenID, though Authelia, and have had limited success. I chose to build from source, and have been trying to leverage config.json for the authentication parameters for Authelia.
After providing the server password, Actual Budget sends me to Authelia to authenticate, and back to Actual Budget, however I get the following error (that I've seen a few times here):

{"status":"error","reason":"openid-grant-failed"}

For reference my config.json looks like:

  "loginMethod": "openid",
  "allowedLoginMethods": ["openid"],
  "openId": {
    "discoveryURL": "https://auth.<my_domain>.com",
    "client_id": "<client_id>",
    "client_secret": "<client_secret>",
    "server_hostname": "https://actual-budget.<my_domain>.com",
    "authMethod": "oauth2"
  }
}

The log from Actual Budget:

2025-05-08T01:54:42.801Z info: GET 304 /account/needs-bootstrap
2025-05-08T01:54:42.830Z info: GET 304 /account/needs-bootstrap
2025-05-08T01:54:42.864Z info: GET 304 /account/needs-bootstrap
2025-05-08T01:54:42.879Z info: GET 304 /admin/owner-created/
Logging in via openid
2025-05-08T01:54:46.383Z info: POST 200 /account/login
OpenID grant failed: OPError: invalid_client (Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method).)
     at processResponse (/opt/actual/actual/node_modules/openid-client/lib/helpers/process_response.js:38:13)
     at Client.grant (/opt/actual/actual/node_modules/openid-client/lib/client.js:1381:22)
     at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
     at async loginWithOpenIdFinalize (file:///opt/actual/actual/packages/sync-server/src/accounts/openid.js:215:18)
     at async file:///opt/actual/actual/packages/sync-server/src/app-openid.js:93:26 {
   error: 'invalid_client',
   error_description: 'Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method).'
 }
2025-05-08T01:54:47.521Z info: GET 400 /openid/callback?code=authelia_ac_HRTN_2GMK4RlAyC-khGJA0BZcOo1LiK47F4jZIcIDFk.qy6C7NsBfsg7-W4Sc2FMgOQ_ujX0Nk6Ipe64wNkB1pI&iss=https%3A%2F%2Fauth.<my_domain>.com&scope=openid+email+profile&state=8ynOYy7hOj8Yt5PWLZX9eqYRvMu8RHzBZZhLr4_Qk3M

This is a snippet of my configuration.yml from Authelia:

identity_providers:
  oidc:
    clients:
      - client_id: "<client_id>"  # read above for how generate
        client_name: "Actual Budget" # will be displayed in Authelia to users
        client_secret: "<client_secret>" # read above for how generate
        public: false
        authorization_policy: "one_factor" # or one_factor, depending on your needs
        redirect_uris:
          - "https://actual-budget.<my_domain>.com/openid/callback"
        scopes:
          - "openid"
          - "profile"
          - "groups"
          - "email"
        userinfo_signed_response_alg: "none"
        token_endpoint_auth_method: "client_secret_basic"

I'm copying the client_id and client_secret directly from Authelia, so I don't imagine it is an issue of the actual credential's mismatching. Anyone have any ideas? Thanks in advance!

Any logs in Authelia?

Thanks for the reply! Yes, this is the log entry for the authentication attempt:

May 08 09:28:54 authelia authelia[385]: time="2025-05-08T09:28:54-04:00" level=error msg="Access Request failed with error: Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method). The provided client secret did not match the registered client secret." method=POST path=/api/oidc/token remote_ip=10.10.20.58

The client_secrets match exactly, so perhaps there is a configuration issue with Actual Budget pulling my config.json?

Looks like the client_id in the config is wrong.
Look for hidden unicode characters. May be regenerate the client_id and add to the config.json again (erase the entire line just in case for hidden characters in the parameter.
Also, look if you are not setting the ENV var for it by mistake.

@lelemm commented on GitHub (May 8, 2025): > > > Hello everyone, I've been trying to implement multi-user via OpenID, though Authelia, and have had limited success. I chose to build from source, and have been trying to leverage config.json for the authentication parameters for Authelia. > > > After providing the server password, Actual Budget sends me to Authelia to authenticate, and back to Actual Budget, however I get the following error (that I've seen a few times here): > > > ``` > > > {"status":"error","reason":"openid-grant-failed"} > > > ``` > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > For reference my `config.json` looks like: > > > ``` > > > "loginMethod": "openid", > > > "allowedLoginMethods": ["openid"], > > > "openId": { > > > "discoveryURL": "https://auth.<my_domain>.com", > > > "client_id": "<client_id>", > > > "client_secret": "<client_secret>", > > > "server_hostname": "https://actual-budget.<my_domain>.com", > > > "authMethod": "oauth2" > > > } > > > } > > > ``` > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > The log from Actual Budget: > > > ``` > > > 2025-05-08T01:54:42.801Z info: GET 304 /account/needs-bootstrap > > > 2025-05-08T01:54:42.830Z info: GET 304 /account/needs-bootstrap > > > 2025-05-08T01:54:42.864Z info: GET 304 /account/needs-bootstrap > > > 2025-05-08T01:54:42.879Z info: GET 304 /admin/owner-created/ > > > Logging in via openid > > > 2025-05-08T01:54:46.383Z info: POST 200 /account/login > > > OpenID grant failed: OPError: invalid_client (Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method).) > > > at processResponse (/opt/actual/actual/node_modules/openid-client/lib/helpers/process_response.js:38:13) > > > at Client.grant (/opt/actual/actual/node_modules/openid-client/lib/client.js:1381:22) > > > at process.processTicksAndRejections (node:internal/process/task_queues:105:5) > > > at async loginWithOpenIdFinalize (file:///opt/actual/actual/packages/sync-server/src/accounts/openid.js:215:18) > > > at async file:///opt/actual/actual/packages/sync-server/src/app-openid.js:93:26 { > > > error: 'invalid_client', > > > error_description: 'Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method).' > > > } > > > 2025-05-08T01:54:47.521Z info: GET 400 /openid/callback?code=authelia_ac_HRTN_2GMK4RlAyC-khGJA0BZcOo1LiK47F4jZIcIDFk.qy6C7NsBfsg7-W4Sc2FMgOQ_ujX0Nk6Ipe64wNkB1pI&iss=https%3A%2F%2Fauth.<my_domain>.com&scope=openid+email+profile&state=8ynOYy7hOj8Yt5PWLZX9eqYRvMu8RHzBZZhLr4_Qk3M > > > ``` > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > This is a snippet of my `configuration.yml` from Authelia: > > > ``` > > > identity_providers: > > > oidc: > > > clients: > > > - client_id: "<client_id>" # read above for how generate > > > client_name: "Actual Budget" # will be displayed in Authelia to users > > > client_secret: "<client_secret>" # read above for how generate > > > public: false > > > authorization_policy: "one_factor" # or one_factor, depending on your needs > > > redirect_uris: > > > - "https://actual-budget.<my_domain>.com/openid/callback" > > > scopes: > > > - "openid" > > > - "profile" > > > - "groups" > > > - "email" > > > userinfo_signed_response_alg: "none" > > > token_endpoint_auth_method: "client_secret_basic" > > > ``` > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > I'm copying the client_id and client_secret directly from Authelia, so I don't imagine it is an issue of the actual credential's mismatching. Anyone have any ideas? Thanks in advance! > > > > > > Any logs in Authelia? > > Thanks for the reply! Yes, this is the log entry for the authentication attempt: > > ``` > May 08 09:28:54 authelia authelia[385]: time="2025-05-08T09:28:54-04:00" level=error msg="Access Request failed with error: Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method). The provided client secret did not match the registered client secret." method=POST path=/api/oidc/token remote_ip=10.10.20.58 > ``` > > The client_secrets match exactly, so perhaps there is a configuration issue with Actual Budget pulling my `config.json`? Looks like the client_id in the config is wrong. Look for hidden unicode characters. May be regenerate the client_id and add to the config.json again (erase the entire line just in case for hidden characters in the parameter. Also, look if you are not setting the ENV var for it by mistake.
Author
Owner

@ParametricToroid commented on GitHub (May 8, 2025):

Looks like the client_id in the config is wrong. Look for hidden unicode characters. May be regenerate the client_id and add to the config.json again (erase the entire line just in case for hidden characters in the parameter. Also, look if you are not setting the ENV var for it by mistake.

I'll give that a try and report back, thanks for your help!

@ParametricToroid commented on GitHub (May 8, 2025): > Looks like the client_id in the config is wrong. Look for hidden unicode characters. May be regenerate the client_id and add to the config.json again (erase the entire line just in case for hidden characters in the parameter. Also, look if you are not setting the ENV var for it by mistake. I'll give that a try and report back, thanks for your help!
Author
Owner

@ParametricToroid commented on GitHub (May 9, 2025):

I was able to get Authelia - Actual Budget authentication working thanks to James (Authelia Core Maintainer) via the Authelia Discord. I wanted to post my configurations here for posterity in case anyone else runs into issues. Thanks to everyone who helped me, I appreciate it.

From Authelia /etc/authelia/configuration.yml:

theme: dark

log:
  level: debug

authentication_backend:
  file:
    path: /etc/authelia/users.yml

access_control:
  default_policy: one_factor
  rules:
    - domain: "actual-budget.<my_domain>.com"
      policy: 'one_factor'
      subject:
      - 'group:actualbudget'

session:
  secret: "<session_secret>"
  name: 'authelia_session'
  same_site: 'lax'
  inactivity: '5m'
  expiration: '1h'
  remember_me: '1M'
  cookies:
    - domain: "<my_domain>.com"
      authelia_url: "https://auth.<my_domain>.com"

storage:
  encryption_key: "<encryption_key>"
  local:
    path: /etc/authelia/db.sqlite

identity_validation:
  reset_password:
    jwt_secret: "<jwt_secret>"
    jwt_lifespan: '5 minutes'
    jwt_algorithm: 'HS256'

notifier:
  filesystem:
    filename: /etc/authelia/emails.txt

identity_providers:
  oidc:
    clients:
      - client_id: '<client_id>'
        client_name: 'Actual Budget'
        client_secret: '<digest of client_secret>'
        public: false
        authorization_policy: 'one_factor'
        redirect_uris:
          - 'https://actual-budget.<my_domain>.com/openid/callback'
        scopes:
          - 'openid'
          - 'groups'
          - 'email'
          - 'profile'
        userinfo_signed_response_alg: 'none'
        token_endpoint_auth_method: 'client_secret_basic'
        grant_types:
          - 'authorization_code'
    jwks:
      - key_id: 'key1'
        algorithm: 'RS256'
        use: 'sig'
        key: |
          -----BEGIN PRIVATE KEY-----
          xxxxxxxxxxxxxxxxxxxxxxxxxxx
          -----END PRIVATE KEY-----

From Actual Budget /opt/actualbudget-data/config.json:

{
  "port": 5006,
  "hostname": "::",
  "serverFiles": "/opt/actualbudget-data/server-files",
  "userFiles": "/opt/actualbudget-data/user-files",
  "trustedProxies": [
    "10.0.0.0/8",
    "172.16.0.0/12",
    "192.168.0.0/16",
    "127.0.0.0/8",
    "::1/128",
    "fc00::/7"
  ],
  "https": {
    "key": "/opt/actualbudget/selfhost.key",
    "cert": "/opt/actualbudget/selfhost.crt"
  },
  "openId": {
    "discoveryURL": "https://auth.<my_domain>.com",
    "client_id": "<client_id>",
    "client_secret": "<client_secret>",
    "server_hostname": "https://actual-budget.<my_domain>.com",
    "authMethod": "openid"
  }
}
@ParametricToroid commented on GitHub (May 9, 2025): I was able to get Authelia - Actual Budget authentication working thanks to James (Authelia Core Maintainer) via the Authelia Discord. I wanted to post my configurations here for posterity in case anyone else runs into issues. Thanks to everyone who helped me, I appreciate it. From Authelia /etc/authelia/configuration.yml: ``` theme: dark log: level: debug authentication_backend: file: path: /etc/authelia/users.yml access_control: default_policy: one_factor rules: - domain: "actual-budget.<my_domain>.com" policy: 'one_factor' subject: - 'group:actualbudget' session: secret: "<session_secret>" name: 'authelia_session' same_site: 'lax' inactivity: '5m' expiration: '1h' remember_me: '1M' cookies: - domain: "<my_domain>.com" authelia_url: "https://auth.<my_domain>.com" storage: encryption_key: "<encryption_key>" local: path: /etc/authelia/db.sqlite identity_validation: reset_password: jwt_secret: "<jwt_secret>" jwt_lifespan: '5 minutes' jwt_algorithm: 'HS256' notifier: filesystem: filename: /etc/authelia/emails.txt identity_providers: oidc: clients: - client_id: '<client_id>' client_name: 'Actual Budget' client_secret: '<digest of client_secret>' public: false authorization_policy: 'one_factor' redirect_uris: - 'https://actual-budget.<my_domain>.com/openid/callback' scopes: - 'openid' - 'groups' - 'email' - 'profile' userinfo_signed_response_alg: 'none' token_endpoint_auth_method: 'client_secret_basic' grant_types: - 'authorization_code' jwks: - key_id: 'key1' algorithm: 'RS256' use: 'sig' key: | -----BEGIN PRIVATE KEY----- xxxxxxxxxxxxxxxxxxxxxxxxxxx -----END PRIVATE KEY----- ``` From Actual Budget /opt/actualbudget-data/config.json: ``` { "port": 5006, "hostname": "::", "serverFiles": "/opt/actualbudget-data/server-files", "userFiles": "/opt/actualbudget-data/user-files", "trustedProxies": [ "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "127.0.0.0/8", "::1/128", "fc00::/7" ], "https": { "key": "/opt/actualbudget/selfhost.key", "cert": "/opt/actualbudget/selfhost.crt" }, "openId": { "discoveryURL": "https://auth.<my_domain>.com", "client_id": "<client_id>", "client_secret": "<client_secret>", "server_hostname": "https://actual-budget.<my_domain>.com", "authMethod": "openid" } } ```
Author
Owner

@Shazib commented on GitHub (May 10, 2025):

#4974 FYI

@Shazib commented on GitHub (May 10, 2025): #4974 FYI
Author
Owner

@mitchplze commented on GitHub (May 14, 2025):

Just popped in to mention that OpenID in Actual is working great with Pocket ID!

I wrote a how-to, in the hope it helps others!

@mitchplze commented on GitHub (May 14, 2025): Just popped in to mention that OpenID in Actual is working great with Pocket ID! I wrote a [how-to](https://pocket-id.org/docs/client-examples/actual), in the hope it helps others!
Author
Owner

@m-schwob commented on GitHub (May 23, 2025):

I didn't followed lately. OpenID works for me for about 2 months without issue. I'm running it in docker along with Authelia and Traefik.

Hope to upgrade to the latest version soon.

@m-schwob commented on GitHub (May 23, 2025): I didn't followed lately. OpenID works for me for about 2 months without issue. I'm running it in docker along with Authelia and Traefik. Hope to upgrade to the latest version soon.
Author
Owner

@0x2142 commented on GitHub (May 28, 2025):

So far working great for me 👍

One request - Can there be an additional role created for a read-only user? In my case, it would be helpful for other people to see how the household is tracking against the budget for a month - but I would prefer to restrict the ability for other people to modify any of the transactions / accounts.

@0x2142 commented on GitHub (May 28, 2025): So far working great for me 👍 One request - Can there be an additional role created for a read-only user? In my case, it would be helpful for other people to see how the household is tracking against the budget for a month - but I would prefer to restrict the ability for other people to modify any of the transactions / accounts.
Author
Owner

@Shazib commented on GitHub (May 28, 2025):

+1 This is working well for me for the last couple weeks using authelia and cloudflare tunnels.

@Shazib commented on GitHub (May 28, 2025): +1 This is working well for me for the last couple weeks using authelia and cloudflare tunnels.
Author
Owner

@m-schwob commented on GitHub (Jun 5, 2025):

Hi, regarding the OIDC experimental feature and user management:

  1. Admin User Behavior
    Currently, the admin user sees all budget files. This can be inconvenient if the admin is also a regular user, as they typically want to view only their own files or those explicitly shared with them. Full access is usually only needed for management purposes.
    A simple solution could be to add a toggle or button that allows the admin to hide files they don't own or that aren't shared with them. Kind of and enable/disable admin mode/view.
    Of course, a dedicated admin dashboard would be ideal, but the toggle would be a good start and an easy fix.

  2. First-Time Sign-In Behavior
    Right now, if a user signs in for the first time before the admin has added them, they encounter a black screen with the error:
    {"status":"error","reason":"openid-grant-failed"}
    A better experience might use part of the behavior of the first user. For example, new users could be automatically added in a "pending approval" state "with no access" while displaying a message like "Waiting for admin approval."
    The admin would then see the user in the management list and could approve them, with all necessary details pulled from the OIDC scopes.
    It would also be great to allow automatic approval based on specific OIDC claims, such as group membership (e.g., if the user belongs to an actual group).

  3. Bug Report: Authelia Session Not Properly Refreshed
    I believe I found a bug when using Authelia as the OIDC provider:

  • Setup: 1 admin and 2 regular users.
  • Log in as user1 and click "Start Fresh."
  • Log out of Actual and Authelia for user1.
  • Log in to Authelia as user2.
  • Log in to Actual.
    Now, instead of showing the "Start Fresh" screen, Actual displays user1’s budget. The UI shows it is logged in as user2, but the "User Access Management" option is missing.
    Clearing the cookies solved the issue, so it seems like the session wasn't properly refreshed.
  1. Logout Handling with Authelia
    I know RP-initiated logout isn't supported by Authelia yet, which makes the logout flow problematic. I've worked with this using Python’s Authlib and found that a good way to detect logout is by monitoring the authelia_session cookie. When logging out via Authelia, this cookie is deleted, and it’s regenerated with a new value upon login. This change can be used to detect session switches.

I'd be happy to contribute to these features. However, I'm not very experienced with JavaScript.

@m-schwob commented on GitHub (Jun 5, 2025): Hi, regarding the OIDC experimental feature and user management: 1. **Admin User Behavior** Currently, the admin user sees all budget files. This can be inconvenient if the admin is also a regular user, as they typically want to view only their own files or those explicitly shared with them. Full access is usually only needed for management purposes. A simple solution could be to add a toggle or button that allows the admin to hide files they don't own or that aren't shared with them. Kind of and enable/disable admin mode/view. Of course, a dedicated admin dashboard would be ideal, but the toggle would be a good start and an easy fix. 2. **First-Time Sign-In Behavior** Right now, if a user signs in for the first time before the admin has added them, they encounter a black screen with the error: `{"status":"error","reason":"openid-grant-failed"}` A better experience might use part of the behavior of the first user. For example, new users could be automatically added in a "pending approval" state "with no access" while displaying a message like "Waiting for admin approval." The admin would then see the user in the management list and could approve them, with all necessary details pulled from the OIDC scopes. It would also be great to allow automatic approval based on specific OIDC claims, such as group membership (e.g., if the user belongs to an `actual` group). 3. **Bug Report: Authelia Session Not Properly Refreshed** I believe I found a bug when using Authelia as the OIDC provider: * Setup: 1 admin and 2 regular users. * Log in as user1 and click "Start Fresh." * Log out of Actual and Authelia for user1. * Log in to Authelia as user2. * Log in to Actual. Now, instead of showing the "Start Fresh" screen, Actual displays user1’s budget. The UI shows it is logged in as user2, but the "User Access Management" option is missing. Clearing the cookies solved the issue, so it seems like the session wasn't properly refreshed. 4. **Logout Handling with Authelia** I know RP-initiated logout isn't supported by Authelia yet, which makes the logout flow problematic. I've worked with this using Python’s Authlib and found that a good way to detect logout is by monitoring the `authelia_session` cookie. When logging out via Authelia, this cookie is deleted, and it’s regenerated with a new value upon login. This change can be used to detect session switches. --- I'd be happy to contribute to these features. However, I'm not very experienced with JavaScript.
Author
Owner

@youngcw commented on GitHub (Jun 5, 2025):

Thanks all that have commented on multi-user and OIDC. The feature is no longer experimental and is an mainlined feature. Please open issues or feature requests going forward.

@youngcw commented on GitHub (Jun 5, 2025): Thanks all that have commented on multi-user and OIDC. The feature is no longer experimental and is an mainlined feature. Please open issues or feature requests going forward.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/actual#1707