Skip to content

Conversation

buger
Copy link
Member

@buger buger commented Oct 14, 2025

User description

TT-15141 Toggling default policy from inactive to active does not activate JWT in some cases (#7431)

User description

TT-15141
Summary Toggling default policy from inactive to active does not activate JWT in some cases
Type Bug Bug
Status In Dev
Points N/A
Labels 2025_long_tail, AI-Complexity-Medium, AI-Priority-High, codilime_refined, customer_bug, jira_escalated

Description

Setting a policy to draft will deactivate keys (as expected), but
setting it back to active does not reactivate the keys when policy is in
draft in time of the first request. Setting the policy back to active
should reactivate the keys.

Related Issue

Motivation and Context

How This Has Been Tested

Screenshots (if appropriate)

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing
    functionality to change)
  • Refactoring or add test (improvements in base code or adds test
    coverage to functionality)

Checklist

  • I ensured that the documentation is up to date
  • I explained why this PR updates go.mod in detail with reasoning
    why it's required
  • I would like a code coverage CI quality gate exception and have
    explained why

PR Type

Bug fix, Enhancement


Description

  • Compute inactivity from applied policies only

  • Persist session state by touching session

  • Refactor inactivity aggregation logic

  • Improve key validity evaluation robustness


Diagram Walkthrough

flowchart LR
  A["Apply(session)"] -- "iterate policyIDs" --> B["Aggregate policy.IsInactive"]
  B -- "result" --> C["sessionInactiveState"]
  C -- "set" --> D["session.IsInactive"]
  A -- "after validations" --> E["session.Touch()"]
Loading

File Walkthrough

Relevant files
Bug fix
apply.go
Aggregate inactivity and persist session via Touch             

internal/policy/apply.go

  • Introduce local sessionInactiveState aggregator.
  • Set session.IsInactive once from aggregated state.
  • Call session.Touch() to persist updated session.
  • Clarify intent with comment on key validity basis.
+8/-1     


Co-authored-by: Radosław Krawczyk 98938598+radkrawczyk@users.noreply.github.com


PR Type

Bug fix, Enhancement


Description

  • Aggregate inactivity across applied policies only

  • Set session.IsInactive from aggregated state

  • Persist updated session via session.Touch()

  • Test updates and policy fixtures adjusted


Diagram Walkthrough

flowchart LR
  A["Apply(session)"] --> B["Iterate applied policy IDs"]
  B -- "OR policy.IsInactive" --> C["Aggregate inactivity"]
  C -- "set" --> D["session.IsInactive"]
  D -- "persist" --> E["session.Touch()"]
Loading

File Walkthrough

Relevant files
Bug fix
apply.go
Aggregate inactivity and persist session via Touch             

internal/policy/apply.go

  • Add local aggregator sessionInactiveState
  • Compute inactivity from applied policies only
  • Assign session.IsInactive once after loop
  • Call session.Touch() to persist session
  • Add clarifying comment on key validity basis
+8/-1     
Tests
apply_test.go
Adjust tests for new inactivity evaluation                             

internal/policy/apply_test.go

  • Update expectations for inactivity with active policies
  • Improve error assertion logic with conditional match
+8/-3     
policies.json
Align policy fixtures with ACL and access rights                 

internal/policy/testdata/policies.json

  • Add access_rights to multiple test policies
  • Enable acl partition where required
  • Ensure rate/quota/complexity partitions align with ACL
+50/-0   

…ctivate JWT in some cases (#7431)

### **User description**
<details open>
<summary><a href="https://tyktech.atlassian.net/browse/TT-15141"
title="TT-15141" target="_blank">TT-15141</a></summary>
  <br />
  <table>
    <tr>
      <th>Summary</th>
<td>Toggling default policy from inactive to active does not activate
JWT in some cases</td>
    </tr>
    <tr>
      <th>Type</th>
      <td>
<img alt="Bug"
src="https://tyktech.atlassian.net/rest/api/2/universal_avatar/view/type/issuetype/avatar/10303?size=medium"
/>
        Bug
      </td>
    </tr>
    <tr>
      <th>Status</th>
      <td>In Dev</td>
    </tr>
    <tr>
      <th>Points</th>
      <td>N/A</td>
    </tr>
    <tr>
      <th>Labels</th>
<td><a
href="https://tyktech.atlassian.net/issues?jql=project%20%3D%20TT%20AND%20labels%20%3D%202025_long_tail%20ORDER%20BY%20created%20DESC"
title="2025_long_tail">2025_long_tail</a>, <a
href="https://tyktech.atlassian.net/issues?jql=project%20%3D%20TT%20AND%20labels%20%3D%20AI-Complexity-Medium%20ORDER%20BY%20created%20DESC"
title="AI-Complexity-Medium">AI-Complexity-Medium</a>, <a
href="https://tyktech.atlassian.net/issues?jql=project%20%3D%20TT%20AND%20labels%20%3D%20AI-Priority-High%20ORDER%20BY%20created%20DESC"
title="AI-Priority-High">AI-Priority-High</a>, <a
href="https://tyktech.atlassian.net/issues?jql=project%20%3D%20TT%20AND%20labels%20%3D%20codilime_refined%20ORDER%20BY%20created%20DESC"
title="codilime_refined">codilime_refined</a>, <a
href="https://tyktech.atlassian.net/issues?jql=project%20%3D%20TT%20AND%20labels%20%3D%20customer_bug%20ORDER%20BY%20created%20DESC"
title="customer_bug">customer_bug</a>, <a
href="https://tyktech.atlassian.net/issues?jql=project%20%3D%20TT%20AND%20labels%20%3D%20jira_escalated%20ORDER%20BY%20created%20DESC"
title="jira_escalated">jira_escalated</a></td>
    </tr>
  </table>
</details>
<!--
  do not remove this marker as it will break jira-lint's functionality.
  added_by_jira_lint
-->

---

<!-- Provide a general summary of your changes in the Title above -->

## Description

Setting a policy to draft will deactivate keys (as expected), but
setting it back to active does not reactivate the keys when policy is in
draft in time of the first request. Setting the policy back to active
should reactivate the keys.

## Related Issue

<!-- This project only accepts pull requests related to open issues. -->
<!-- If suggesting a new feature or change, please discuss it in an
issue first. -->
<!-- If fixing a bug, there should be an issue describing it with steps
to reproduce. -->
<!-- OSS: Please link to the issue here. Tyk: please create/link the
JIRA ticket. -->

## Motivation and Context

<!-- Why is this change required? What problem does it solve? -->

## How This Has Been Tested

<!-- Please describe in detail how you tested your changes -->
<!-- Include details of your testing environment, and the tests -->
<!-- you ran to see how your change affects other areas of the code,
etc. -->
<!-- This information is helpful for reviewers and QA. -->

## Screenshots (if appropriate)

## Types of changes

<!-- What types of changes does your code introduce? Put an `x` in all
the boxes that apply: -->

- [x] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Refactoring or add test (improvements in base code or adds test
coverage to functionality)

## Checklist

<!-- Go over all the following points, and put an `x` in all the boxes
that apply -->
<!-- If there are no documentation updates required, mark the item as
checked. -->
<!-- Raise up any additional concerns not covered by the checklist. -->

- [ ] I ensured that the documentation is up to date
- [ ] I explained why this PR updates go.mod in detail with reasoning
why it's required
- [ ] I would like a code coverage CI quality gate exception and have
explained why


___

### **PR Type**
Bug fix, Enhancement


___

### **Description**
- Compute inactivity from applied policies only

- Persist session state by touching session

- Refactor inactivity aggregation logic

- Improve key validity evaluation robustness


___

### Diagram Walkthrough


```mermaid
flowchart LR
  A["Apply(session)"] -- "iterate policyIDs" --> B["Aggregate policy.IsInactive"]
  B -- "result" --> C["sessionInactiveState"]
  C -- "set" --> D["session.IsInactive"]
  A -- "after validations" --> E["session.Touch()"]
```



<details> <summary><h3> File Walkthrough</h3></summary>

<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Bug
fix</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>apply.go</strong><dd><code>Aggregate inactivity and
persist session via Touch</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></summary>
<hr>

internal/policy/apply.go

<ul><li>Introduce local <code>sessionInactiveState</code>
aggregator.<br> <li> Set <code>session.IsInactive</code> once from
aggregated state.<br> <li> Call <code>session.Touch()</code> to persist
updated session.<br> <li> Clarify intent with comment on key validity
basis.</ul>


</details>


  </td>
<td><a
href="https://github.com/TykTechnologies/tyk/pull/7431/files#diff-59b92e9d31f142f1d99b746eb3ff7db4e26bf6c3044c9b87b58034a947ee04d1">+8/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr></tr></tbody></table>

</details>

___

---------

Co-authored-by: Radosław Krawczyk <98938598+radkrawczyk@users.noreply.github.com>

(cherry picked from commit f4ee0c5)
@buger buger enabled auto-merge (squash) October 14, 2025 06:54
Copy link
Contributor

API Changes

no api changes detected

Copy link
Contributor

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
General
Improve unexpected error reporting

Replace t.Fail() with a failure that includes the unexpected error for
debuggability. As-is, it drops the error detail and makes failures harder to
diagnose.

internal/policy/apply_test.go [1293-1301]

 if err := service.Apply(sess); err != nil {
   if tc.errMatch != "" {
     assert.ErrorContains(t, err, tc.errMatch)
   } else {
-    t.Fail()
+    t.Fatalf("unexpected error: %v", err)
   }
 
   return
 }
Suggestion importance[1-10]: 6

__

Why: Replacing t.Fail() with t.Fatalf("unexpected error: %v", err) improves test diagnostics without changing logic. It’s a minor but useful readability/debuggability enhancement.

Low
Touch only on success

Avoid touching the session after returning an error path. Ensure session.Touch() is
only reached on success and consider moving it earlier could be fine, but ensure
it's not executed when an error is returned.

internal/policy/apply.go [246-248]

 if len(rights) == 0 && policyIDs != nil {
   return errors.New("key has no valid policies to be applied")
 }
 
+// Mark session as updated only on successful application.
 session.Touch()
Suggestion importance[1-10]: 5

__

Why: session.Touch() is already after the error return, so it only executes on success; the suggestion restates current behavior with no functional change. It’s accurate but low impact.

Low
Possible issue
Preserve prior inactive state

Preserve a pre-existing inactive session state when evaluating policy activity. If
session.IsInactive was already true before applying policies, the new logic resets
it to false when all policies are active, which may unintentionally reactivate the
key.

internal/policy/apply.go [113-116]

 // Only the status of policies applied to a key should determine the validity of the key.
-sessionInactiveState := false
+// Preserve pre-existing inactive session state.
+sessionInactiveState := session.IsInactive
 ...
 sessionInactiveState = sessionInactiveState || policy.IsInactive
 ...
 session.IsInactive = sessionInactiveState
Suggestion importance[1-10]: 3

__

Why: The PR intentionally changes semantics to base session.IsInactive solely on applied policies, resetting any pre-existing inactive state; the suggestion contradicts this goal. While technically harmless code-wise, it undermines the PR’s stated behavior.

Low

Copy link

@buger buger merged commit cce81c1 into release-5.8 Oct 14, 2025
36 of 38 checks passed
@buger buger deleted the merge/release-5.8/f4ee0c5262d11850728697d595c7f5b380ced905 branch October 14, 2025 07:21
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.

2 participants