Expired OAuth tokens not deleted in Redis

Branch/Environment/Version

  • Branch/Version: Release 5.8.7
  • Environment: On-prem

Describe the bug
Our Redis memory usage is ever growing, and it contains nearly only entries of type apikey-,
although we have configured TYK_GW_OAUTHTOKENEXPIREDRETAINPERIOD=1800 and
TYK_GW_OAUTHTOKENEXPIRE, which should lead to tokens being deleted in Redis after 1 hour,
according to the documentation (as we understand it).

Reproduction steps
Steps to reproduce the behaviour:

  1. Add any api
  2. Configure TYK_GW_OAUTHTOKENEXPIREDRETAINPERIOD
  3. Let clients create lots of OAuth tokens continuously
  4. Check Redis database capacity usage

Actual behaviour
Old apikey-* entries are never deleted in Redis.

Expected behaviour
Keys older than 1 hour should automatically be deleted.

Configuration (tyk config file):
Environment variables for Tyk Gateway K8s pod:

      - env:
        - name: TYK_GW_LISTENPORT
          value: "8080"
        - name: TYK_GW_OAS_VALIDATE_EXAMPLES
          value: "false"
        - name: TYK_GW_OAS_VALIDATE_SCHEMA_DEFAULTS
          value: "false"
        - name: TYK_GW_ENABLEFIXEDWINDOWRATELIMITER
          value: "false"
        - name: TYK_GW_STORAGE_TLSMAXVERSION
        - name: TYK_GW_STORAGE_TLSMINVERSION
        - name: REDIGOCLUSTER_SHARDCOUNT
          value: "128"
        - name: TYK_GW_STORAGE_TYPE
          value: redis
        - name: TYK_GW_STORAGE_ADDRS
          value: master.***:6379
        - name: TYK_GW_STORAGE_ENABLECLUSTER
          value: "false"
        - name: TYK_GW_STORAGE_DATABASE
          value: "0"
        - name: TYK_GW_STORAGE_PASSWORD
          valueFrom:
            secretKeyRef:
              key: redisPass
              name: secrets-trip-api
        - name: TYK_GW_STORAGE_USESSL
          value: "true"
        - name: TYK_GW_SECRET
          valueFrom:
            secretKeyRef:
              key: APISecret
              name: secrets-trip-api
        - name: TYK_GW_NODESECRET
          valueFrom:
            secretKeyRef:
              key: APISecret
              name: secrets-trip-api
        - name: TYK_GW_POLICIES_ALLOWEXPLICITPOLICYID
          value: "true"
        - name: TYK_GW_HTTPSERVEROPTIONS_USESSL
          value: "false"
        - name: TYK_GW_TEMPLATEPATH
          value: /opt/tyk-gateway/templates
        - name: TYK_GW_TYKJSPATH
          value: /opt/tyk-gateway/js/tyk.js
        - name: TYK_GW_MIDDLEWAREPATH
          value: /mnt/tyk-gateway/middleware
        - name: TYK_GW_APPPATH
          value: /mnt/tyk-gateway/apps
        - name: TYK_GW_POLICIES_POLICYPATH
          value: /mnt/tyk-gateway/policies
        - name: TYK_GW_STORAGE_MAXIDLE
          value: "1000"
        - name: TYK_GW_ENABLENONTRANSACTIONALRATELIMITER
          value: "true"
        - name: TYK_GW_POLICIES_POLICYSOURCE
          value: file
        - name: TYK_GW_ENABLEANALYTICS
          value: "true"
        - name: TYK_GW_ANALYTICSCONFIG_TYPE
        - name: TYK_GW_POLICIES_POLICYRECORDNAME
          value: /mnt/tyk-gateway/policies/policies.json
        - name: TYK_GW_HASHKEYS
          value: "true"
        - name: TYK_GW_HASHKEYFUNCTION
          value: murmur128
        - name: TYK_GW_HTTPSERVEROPTIONS_ENABLEWEBSOCKETS
          value: "true"
        - name: TYK_GW_HTTPSERVEROPTIONS_MINVERSION
          value: "771"
        - name: TYK_GW_HTTPSERVEROPTIONS_CERTIFICATES
          value: '[{"cert_file":"/etc/certs/tyk-gateway/tls.crt","domain_name":"*","key_file":"/etc/certs/tyk-gateway/tls.key"}]'
        - name: TYK_GW_HTTPSERVEROPTIONS_SSLINSECURESKIPVERIFY
          value: "false"
        - name: TYK_GW_ALLOWINSECURECONFIGS
          value: "true"
        - name: TYK_GW_COPROCESSOPTIONS_ENABLECOPROCESS
          value: "true"
        - name: TYK_GW_MAXIDLECONNSPERHOST
          value: "500"
        - name: TYK_GW_ENABLECUSTOMDOMAINS
          value: "true"
        - name: TYK_GW_PIDFILELOCATION
          value: /mnt/tyk-gateway/tyk.pid
        - name: TYK_GW_DBAPPCONFOPTIONS_NODEISSEGMENTED
          value: "false"
        - name: TYK_GW_HTTPSERVEROPTIONS_ENABLEHTTP2
          value: "true"
        - name: TYK_GW_HTTPSERVEROPTIONS_FLUSHINTERVAL
          value: "1"
        - name: TYK_GW_PROXYENABLEHTTP2
          value: "true"
        - name: TYK_GW_LOGLEVEL
          value: info
        - name: TYK_GW_HTTPSERVEROPTIONS_READTIMEOUT
          value: "660"
        - name: TYK_GW_HTTPSERVEROPTIONS_WRITETIMEOUT
          value: "660"
        - name: TYK_GW_OAUTHTOKENEXPIREDRETAINPERIOD
          value: "1800"
        - name: TYK_GW_OAUTHTOKENEXPIRE
          value: "1800"
        - name: TYK_GW_GLOBALSESSIONLIFETIME
          value: "3600"

Hello Dirk,

We understand that this configuration may have caused some confusion, and we sincerely appreciate your patience.
oauth_token_expired_retain_period specifies the retain period for your tokens. This is used to clean up tokens with a score up to your current timestamp minus the retention period you set.
This will not automatically remove the token, you will still need to call the /tyk/oauth/clients/APIID/KeyName/tokens via the Gateway API endpoint for it to be removed.

With that, kindly invoke the /tyk/oauth/clients/APIID/ClientID/tokens endpoint and see if the tokens are removed on your end.

Regards

Hey Isaac,

thanks for the reply. I’m pretty confused about this now. Does it mean that there is no way to automatically delete expired tokens from Redis, and that I always need to actively call the API to clean up?

Regards

Dirk

Hi @Dirk,

Thank you for your patience.

Unfortunately, TYK_GW_OAUTHTOKENEXPIREDRETAINPERIOD is currently not respected and has no effect. This is a known issue and is tracked under defect TT-12733.

For TYK_GW_GLOBALSESSIONLIFETIME to take effect, TYK_GW_FORCEGLOBALSESSIONLIFETIME=true must also be set.

Please note that Tyk does not explicitly delete keys. Instead, it sets a TTL on keys at creation time, and Redis automatically removes them when the TTL expires. Consequently, any previously existing keys will need to be manually deleted.

As an alternative, you can set a non-zero session_lifetime in the API definition, and enable TYK_GW_SESSIONLIFETIMERESPECTSKEYEXPIRATION on the Gateway. Tyk will apply the larger of the two values (session_lifetime vs the key’s expiry) when setting the key TTL.

Please see this reference for more details on the nuances, configuration options and behaviour of key expiry and deletion.

Hope this helps.

Best regards,