mirror of
https://github.com/go-gitea/gitea.git
synced 2026-07-17 06:32:41 -05:00
Thoughts and Best Practices in Desiging API Access Token #2251
Open
opened 2025-11-02 04:29:31 -06:00 by GiteaMirror
·
2 comments
No Branch/Tag Specified
main
release/v1.25
release/v1.24
release/v1.23
release/v1.22
release/v1.21
release/v1.20
release/v1.19
release/v1.18
release/v1.17
release/v1.16
release/v1.15
release/v1.14
release/v1.13
release/v1.12
release/v1.11
release/v1.10
release/v1.9
release/v1.8
v1.25.3
v1.25.2
v1.25.1
v1.25.0
v1.24.7
v1.25.0-rc0
v1.26.0-dev
v1.24.6
v1.24.5
v1.24.4
v1.24.3
v1.24.2
v1.24.1
v1.24.0
v1.23.8
v1.24.0-rc0
v1.25.0-dev
v1.23.7
v1.23.6
v1.23.5
v1.23.4
v1.23.3
v1.23.2
v1.23.1
v1.23.0
v1.23.0-rc0
v1.24.0-dev
v1.22.6
v1.22.5
v1.22.4
v1.22.3
v1.22.2
v1.22.1
v1.22.0
v1.23.0-dev
v1.22.0-rc1
v1.21.11
v1.22.0-rc0
v1.21.10
v1.21.9
v1.21.8
v1.21.7
v1.21.6
v1.21.5
v1.21.4
v1.21.3
v1.21.2
v1.20.6
v1.21.1
v1.21.0
v1.21.0-rc2
v1.21.0-rc1
v1.20.5
v1.22.0-dev
v1.21.0-rc0
v1.20.4
v1.20.3
v1.20.2
v1.20.1
v1.20.0
v1.19.4
v1.21.0-dev
v1.20.0-rc2
v1.20.0-rc1
v1.20.0-rc0
v1.19.3
v1.19.2
v1.19.1
v1.19.0
v1.19.0-rc1
v1.20.0-dev
v1.19.0-rc0
v1.18.5
v1.18.4
v1.18.3
v1.18.2
v1.18.1
v1.18.0
v1.17.4
v1.18.0-rc1
v1.19.0-dev
v1.18.0-rc0
v1.17.3
v1.17.2
v1.17.1
v1.17.0
v1.17.0-rc2
v1.16.9
v1.17.0-rc1
v1.18.0-dev
v1.16.8
v1.16.7
v1.16.6
v1.16.5
v1.16.4
v1.16.3
v1.16.2
v1.16.1
v1.16.0
v1.15.11
v1.17.0-dev
v1.16.0-rc1
v1.15.10
v1.15.9
v1.15.8
v1.15.7
v1.15.6
v1.15.5
v1.15.4
v1.15.3
v1.15.2
v1.15.1
v1.14.7
v1.15.0
v1.15.0-rc3
v1.14.6
v1.15.0-rc2
v1.14.5
v1.16.0-dev
v1.15.0-rc1
v1.14.4
v1.14.3
v1.14.2
v1.14.1
v1.14.0
v1.13.7
v1.14.0-rc2
v1.13.6
v1.13.5
v1.14.0-rc1
v1.15.0-dev
v1.13.4
v1.13.3
v1.13.2
v1.13.1
v1.13.0
v1.12.6
v1.13.0-rc2
v1.14.0-dev
v1.13.0-rc1
v1.12.5
v1.12.4
v1.12.3
v1.12.2
v1.12.1
v1.11.8
v1.12.0
v1.11.7
v1.12.0-rc2
v1.11.6
v1.12.0-rc1
v1.13.0-dev
v1.11.5
v1.11.4
v1.11.3
v1.10.6
v1.12.0-dev
v1.11.2
v1.10.5
v1.11.1
v1.10.4
v1.11.0
v1.11.0-rc2
v1.10.3
v1.11.0-rc1
v1.10.2
v1.10.1
v1.10.0
v1.9.6
v1.9.5
v1.10.0-rc2
v1.11.0-dev
v1.10.0-rc1
v1.9.4
v1.9.3
v1.9.2
v1.9.1
v1.9.0
v1.9.0-rc2
v1.10.0-dev
v1.9.0-rc1
v1.8.3
v1.8.2
v1.8.1
v1.8.0
v1.8.0-rc3
v1.7.6
v1.8.0-rc2
v1.7.5
v1.8.0-rc1
v1.9.0-dev
v1.7.4
v1.7.3
v1.7.2
v1.7.1
v1.7.0
v1.7.0-rc3
v1.6.4
v1.7.0-rc2
v1.6.3
v1.7.0-rc1
v1.7.0-dev
v1.6.2
v1.6.1
v1.6.0
v1.6.0-rc2
v1.5.3
v1.6.0-rc1
v1.6.0-dev
v1.5.2
v1.5.1
v1.5.0
v1.5.0-rc2
v1.5.0-rc1
v1.5.0-dev
v1.4.3
v1.4.2
v1.4.1
v1.4.0
v1.4.0-rc3
v1.4.0-rc2
v1.3.3
v1.4.0-rc1
v1.3.2
v1.3.1
v1.3.0
v1.3.0-rc2
v1.3.0-rc1
v1.2.3
v1.2.2
v1.2.1
v1.2.0
v1.2.0-rc3
v1.2.0-rc2
v1.1.4
v1.2.0-rc1
v1.1.3
v1.1.2
v1.1.1
v1.1.0
v1.0.2
v1.0.1
v1.0.0
v0.9.99
Labels
Clear labels
$20
$250
$50
$500
backport/done
💎 Bounty
docs-update-needed
good first issue
hacktoberfest
issue/bounty
issue/confirmed
issue/critical
issue/duplicate
issue/needs-feedback
issue/not-a-bug
issue/regression
issue/stale
issue/workaround
lgtm/need 2
modifies/api
modifies/translation
outdated/backport/v1.18
outdated/theme/markdown
outdated/theme/timetracker
performance/bigrepo
performance/cpu
performance/memory
performance/speed
pr/breaking
proposal/accepted
proposal/rejected
pr/wip
pull-request
reviewed/wontfix
💰 Rewarded
skip-changelog
status/blocked
topic/accessibility
topic/api
topic/authentication
topic/build
topic/code-linting
topic/commit-signing
topic/content-rendering
topic/deployment
topic/distribution
topic/federation
topic/gitea-actions
topic/issues
topic/lfs
topic/mobile
topic/moderation
topic/packages
topic/pr
topic/projects
topic/repo
topic/repo-migration
topic/security
topic/theme
topic/ui
topic/ui-interaction
topic/ux
topic/webhooks
topic/wiki
type/bug
type/deprecation
type/docs
type/enhancement
type/feature
type/miscellaneous
type/proposal
type/question
type/refactoring
type/summary
type/testing
type/upstream
Mirrored from GitHub Pull Request
No Label
type/proposal
Milestone
No items
No Milestone
Projects
Clear projects
No project
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: github-starred/gitea#2251
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @beeonthego on GitHub (Aug 26, 2018).
Thank you all contributors for making this open source project.
We are building an app that will use Gitea at the backend. The App will primarily access gitea through API. We would like the app to be able to scale, and would like to check access token at API gateway before the requests hit gitea instance. Ideally the decision can be made at API gateway without db query.
This is not possible with the current implementation of gitea access token, and refactoring of access token data model is required. Here are our initial thoughts on the design of the API access token while maintaining backward compatibility. Before submitting a pull request, we would like to hear the thoughts and best practices of people using the project now.
Use JWT Bearer Token as API access token
The bearer token carries extra claims that can be checked on a different machine, using shared secret server key.
Care must be taken to implement JWT access token properly.
Security
The overall design principle is that in case a database is compromised, the damage is contained to the information loss only and no further privilege can be obtained.
To address the security concerns raised in issue #3789, the token can be signed with a strong and permanent server key. The key should be long enough and beyond the possibility of brute force attack.
The key name and claims can be stored in the database to track what keys have been issued, and to be used in key admin UI. However only the API keys signed with server secret will be able to access the API. The API is not accessible using the information from the database alone.
The key can be set as environment variable, so gitea admin can decide the key length depending on their needs for security and performance, with a minimum of 256 bits (32 bytes).
The claims can be signed with a single algorithm (eg HS256) to avoid the flaws of JWT (eg tampering on signing algorithm and signature). This is also how drone signs access token now.
Backward Compatibility
In order for the issued access tokens to continue to work (eg drone integration), the implementation can check the length of access token. if it is exactly 40 bytes long (sha1 hash), the current logic is applied (retrieving the key from db and check permissions). If the token is longer than 40 bytes, then new logic will be used.
When users log into Drone instance using gitea password, Drone will automatically retrieve the new access token and save it in drone db for future use. The transition will be seamless, and can take whatever time it requires.
data storage
The new claims can be added on top of the existing fields so the table can hold both the old issued tokens, and new information. This way old access tokens will continue to work until revoked or replaced with new tokens.
other benefits of using JWT bearer token
Users can decide to grant full access, or partial access to a token, eg by repo, api routes (regular expression), request methods. Details of the claims are to be discussed.
[edit]
With JWT and hs256 signing algorithm in place, it is possible to store the claims i/o access token in Drone db, and use the same secret server key on drone to sign the access token before making api requests to gitea server. This involves some code change in Drone server, which is easy to customize and implement. This storage strategy in drone gives peace of mind in case the drone db is compromised. People can't do much with the claims only found in drone db.
proposed composite signing key (u.Rands + u.Salt + hash with fixed server secret)
The disadvantage of signing token with a fixed server secret is that token is tied with a server secret. In order to revoke a token, a new server secret must be used thus revoking all tokens. This may not be realistic in multi user environment. The same problem exists with expiring tokens and refreshing tokens. Refreshing token is valid for a long time. A new server secret is required in order to revoke a lost refreshing token.
To maintain security and flexibility, we propose to sign tokens with a composite key including some variable strings per user, plus a hash with server secret. For example, it is possible to sign access token with individual user's rands and salts + hash.
The disadvantage is that a db query is required in order to check the validity of access token. Scaling an application with this approach means scaling the database at the same time.
This can be offered as an option and turned on with an environment variable. If true, then each token will be signed and checked using individual composite keys instead of a permanent server key. Otherwise, a fixed server secret will be used for signing.
We are writing the code to implement this internally. Collaboration on XORM, UI and test suites are welcome.
Your thoughts and suggestions?
@beeonthego commented on GitHub (Aug 28, 2018):
Just submitted a PR #4806 to have some custom grants/claims parameters code to look at. comments are welcome.
@beeonthego commented on GitHub (Aug 31, 2018):
Here are the proposed changes to the api AccessToken struct. Can someone work on this and make a pull request to add claims column in db? Our code depends on this change in data structure.
When you prepare db migration, please update the values of this column in existing tokens to an empty string. gitea will panic if this column is left as NULL. thanks.