Skip to content

Add auditlog for JWT and legacy tokens#3673

Merged
stveit merged 7 commits intomasterfrom
add-auditlog-for-jwt-tokens
Dec 12, 2025
Merged

Add auditlog for JWT and legacy tokens#3673
stveit merged 7 commits intomasterfrom
add-auditlog-for-jwt-tokens

Conversation

@stveit
Copy link
Copy Markdown
Contributor

@stveit stveit commented Dec 9, 2025

Scope and purpose

Fixes #3405 . Based on #3674

Adds Auditlog for legacy and JWT tokens. Alot of the auditlogging was there already, it just needed a few adjustments and actually showing the auditlog table in the frontend

Auditlog entries for tokens get messed up when you delete the token, it seems like part of the auditlog requires the referred object to exist for it to have all the information, so when an object is deleted you lose info. This has a related issue #1727, but I'm not sure I've experienced entire entries being deleted, only that the entries are missing the object value

Contributor Checklist

Every pull request should have this checklist filled out, no matter how small it is.
More information about contributing to NAV can be found in the
Hacker's guide to NAV.

  • Added a changelog fragment for towncrier
  • Added/amended tests for new/changed code
  • Added/changed documentation
  • Linted/formatted the code with ruff, easiest by using pre-commit
  • Wrote the commit message so that the first line continues the sentence "If applied, this commit will ...", starts with a capital letter, does not end with punctuation and is 50 characters or less long. See https://cbea.ms/git-commit/
  • Based this pull request on the correct upstream branch: For a patch/bugfix affecting the latest stable version, it should be based on that version's branch (<major>.<minor>.x). For a new feature or other additions, it should be based on master.
  • If applicable: Created new issues if this PR does not fix the issue completely/there is further work to be done
  • If it's not obvious from a linked issue, described how to interact with NAV in order for a reviewer to observe the effects of this change first-hand (commands, URLs, UI interactions)
  • If this results in changes in the UI: Added screenshots of the before and after
  • If this adds a new Python source code file: Added the boilerplate header to that file

@stveit stveit self-assigned this Dec 9, 2025
@github-actions
Copy link
Copy Markdown

github-actions bot commented Dec 9, 2025

Test results

    27 files      27 suites   44m 59s ⏱️
 2 729 tests  2 729 ✅ 0 💤 0 ❌
20 222 runs  20 222 ✅ 0 💤 0 ❌

Results for commit b1f2dd6.

♻️ This comment has been updated with latest results.

@codecov
Copy link
Copy Markdown

codecov bot commented Dec 9, 2025

Codecov Report

❌ Patch coverage is 76.19048% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 63.07%. Comparing base (ce83801) to head (b1f2dd6).
⚠️ Report is 390 commits behind head on master.

Files with missing lines Patch % Lines
python/nav/web/useradmin/views.py 76.19% 5 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3673      +/-   ##
==========================================
+ Coverage   63.04%   63.07%   +0.03%     
==========================================
  Files         612      612              
  Lines       45230    45237       +7     
  Branches       43       43              
==========================================
+ Hits        28513    28531      +18     
+ Misses      16707    16696      -11     
  Partials       10       10              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@stveit stveit force-pushed the add-auditlog-for-jwt-tokens branch from 1b961ca to 2114e14 Compare December 10, 2025 13:27
@stveit stveit changed the base branch from master to add-missing-success-messages-jwt December 10, 2025 13:27
@stveit stveit marked this pull request as ready for review December 10, 2025 15:26
@stveit stveit changed the title Add auditlog for jwt tokens Add auditlog for JWT and legacy tokens Dec 11, 2025
Copy link
Copy Markdown
Member

@lunkwill42 lunkwill42 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks OK to me, but I would like @hmpf to sign off on it too.

Two things hit, me though, and the first of them is a biggie, IMHO:

  1. 🔴 Legacy opaque tokens are identified by their actual token string in the audit log, meaning the actual, usable tokens are leaking everywhere in the logs. This is just plain stupid and a borderline security issue.
  2. I don't really understand #1727. The LogEntry model uses a LegacyGenericForeignKey to link to objects, and does not specify any sort of cascading delete rule (which would be hard, since generic foreign keys do not enforce integrity at the database level anyway). Deleting a target object from NAV only results in the foreign key of the LogEntry to become an invalid foreign key. When attempting to resolve it, you will hit a dead end. We haven't really lost anything - but we can know that the target is referring to some object that no longer exists, and we can be explicit about that to the user (i.e. instead of a blank in the target column, there would be a message that "target X has been deleted" from NAV).

None of these are issues with this PR, however, but we should have a discussion of them, nonetheless, @hmpf.

@hmpf
Copy link
Copy Markdown
Contributor

hmpf commented Dec 11, 2025

Point 1 needs an issue, bugfix and/or security. It's probably because APIToken's "str" is just the token itself. Changing away from that should be done in general, it is not safe. It is better to only access the actual token explicitly.

We cannot special case this in LogEntry itself, that way madness lies. We could actually rewrite the existing auditlog for apitokens to use object.pk instead.

Talking about auditlog, it should be possible to filter by object type and target type and maybe search in description.

@hmpf
Copy link
Copy Markdown
Contributor

hmpf commented Dec 11, 2025

Point 2, lets try deleting any of the objects pointed to from the auditlog and if the specific entry survives, close #1727. Agreed that when an object pointed to is deleted it should be shown as "deleted" or similar.

@hmpf
Copy link
Copy Markdown
Contributor

hmpf commented Dec 11, 2025

.. it would be possible, for point 1, to in python/nav/web/useradmin/views.py futz with the object that is given to the LogEntry methods just for the tokens. I'm thinking of:

  • TokenCreate
  • TokenEdit
  • TokenDelete
  • token_expire

Override object.token with a safe string, that would fix the description field. It will not fix the rendering of the actual object in the auditlog list though, there we'd have to examine every object and make it safe on print.

Or we could fix ApiToken.__str__.

@hmpf
Copy link
Copy Markdown
Contributor

hmpf commented Dec 11, 2025

.. we could also add a censored()-method to the ApiToken and have AuditLog attempt to call object.censored() before falling back to str(object).

@stveit stveit force-pushed the add-missing-success-messages-jwt branch from 7b05136 to 5bbdb24 Compare December 11, 2025 15:31
Copy link
Copy Markdown
Contributor

@johannaengland johannaengland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very clean!

I noticed that you added tests for the JWT token creation/editing/etc, but the changes in the classic token creation are uncovered, so either in this PR or as a follow up issue you could add tests for that as well

Comment on lines +91 to +94
logentry = LogEntry.objects.filter(
object_pk=token.pk, verb='create-jwtrefreshtoken'
)
assert logentry.exists()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason you're doing it here in two lines and then in the next test in one line?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assure you there is no good reason for that

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that you added tests for the JWT token creation/editing/etc, but the changes in the classic token creation are uncovered, so either in this PR or as a follow up issue you could add tests for that as well

yeah I dont think the old token system has tests to begin with, so I neglected it. Its supposed to be removed at some point so not the most important thing in the world. Could potentially do it in a different PR and base the tests off the JWT tests here. Not sure when we're planning on removing it so if it sticks around the tests will prob be worthwhile

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Base automatically changed from add-missing-success-messages-jwt to master December 12, 2025 13:41
This feature is not called expiry, its called recreate
the `delete` function for generic DeleteViews apparantly is not called,
you need to override form_valid instead.
@stveit stveit force-pushed the add-auditlog-for-jwt-tokens branch from 2114e14 to b6c6b58 Compare December 12, 2025 13:55
@stveit stveit force-pushed the add-auditlog-for-jwt-tokens branch from b6c6b58 to b1f2dd6 Compare December 12, 2025 14:09
@sonarqubecloud
Copy link
Copy Markdown

@stveit stveit merged commit 4c0533f into master Dec 12, 2025
18 checks passed
@stveit stveit deleted the add-auditlog-for-jwt-tokens branch December 12, 2025 14:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add audit log for creation of tokens

4 participants