diff --git a/.env.template b/.env.template
index 05ab3a8960882958c0e9f1043fa87f61579272d1..3990d028175b9cdfb675a7ddadd3c140deeb81f7 100644
--- a/.env.template
+++ b/.env.template
@@ -22,5 +22,6 @@ DATABASE_NAME
 
 BO_API_TOKEN
 
+FETCH_GRDF_TOKEN=true
 GRDF_CLIENT_ID
 GRDF_CLIENT_SECRET
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 258ea3124f8cffde8471803535840b6f3d4b2f60..25133644736f3249e615543f916370d2ba26208d 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -25,7 +25,7 @@ stages:
   - deploy
 
 import-convert-assets:
-  image: alpine:3.16.2
+  image: alpine:3.20.3
   stage: import-convert-assets
   before_script:
     - apk add inkscape curl
@@ -142,6 +142,7 @@ deploy_rec:
     - sed -i "s/{{CLIENT_ID}}/$REC_CLIENT_ID/" ./k8s/secrets/ecolyo-agent-server-config.yml
     - sed -i "s/{{CLIENT_SECRET}}/$REC_CLIENT_SECRET/" ./k8s/secrets/ecolyo-agent-server-config.yml
     - sed -i "s/{{BO_API_TOKEN}}/$REC_BO_API_TOKEN/" ./k8s/secrets/ecolyo-agent-server-config.yml
+    - sed -i "s/{{FETCH_GRDF_TOKEN}}/\"$REC_FETCH_GRDF_TOKEN\"/" ./k8s/secrets/ecolyo-agent-server-config.yml
     - sed -i "s/{{GRDF_CLIENT_ID}}/$GRDF_CLIENT_ID/" ./k8s/secrets/ecolyo-agent-server-config.yml
     - sed -i "s/{{GRDF_CLIENT_SECRET}}/$GRDF_CLIENT_SECRET/" ./k8s/secrets/ecolyo-agent-server-config.yml
     - sed -i "s/{{HOSTNAME}}/ecolyo-agent-rec.apps.grandlyon.com/g" ./k8s/secrets/ecolyo-agent-server-config.yml
@@ -152,7 +153,7 @@ deploy_rec:
   script:
     - find k8s/ -name '*.yml' -exec sed -i "s/{{NS}}/$NAMESPACE/g" {} \;
 
-    - oc create secret -n $NAMESPACE docker-registry llle-project --docker-server=$CI_REGISTRY --docker-username=llle-project --docker-password=$READ_REGISTRY_TOKEN --dry-run=client -o yaml | oc apply -f -
+    - oc create secret -n $NAMESPACE docker-registry forge-secret --docker-server=$CI_REGISTRY --docker-username=read_registry --docker-password=$READ_REGISTRY_TOKEN --dry-run=client -o yaml | oc apply -f -
 
     - oc apply -f k8s/secrets
     - oc apply -f k8s/deployments
@@ -174,6 +175,7 @@ deploy_prod:
     - sed -i "s/{{CLIENT_ID}}/$PROD_CLIENT_ID/" ./k8s/secrets/ecolyo-agent-server-config.yml
     - sed -i "s/{{CLIENT_SECRET}}/$PROD_CLIENT_SECRET/" ./k8s/secrets/ecolyo-agent-server-config.yml
     - sed -i "s/{{BO_API_TOKEN}}/$PROD_BO_API_TOKEN/" ./k8s/secrets/ecolyo-agent-server-config.yml
+    - sed -i "s/{{FETCH_GRDF_TOKEN}}/\"$PROD_FETCH_GRDF_TOKEN\"/" ./k8s/secrets/ecolyo-agent-server-config.yml
     - sed -i "s/{{GRDF_CLIENT_ID}}/$GRDF_CLIENT_ID/" ./k8s/secrets/ecolyo-agent-server-config.yml
     - sed -i "s/{{GRDF_CLIENT_SECRET}}/$GRDF_CLIENT_SECRET/" ./k8s/secrets/ecolyo-agent-server-config.yml
     - sed -i "s/{{HOSTNAME}}/ecolyo-agent.apps.grandlyon.com/g" ./k8s/secrets/ecolyo-agent-server-config.yml
@@ -184,7 +186,7 @@ deploy_prod:
   script:
     - find k8s/ -name '*.yml' -exec sed -i "s/{{NS}}/$NAMESPACE/g" {} \;
 
-    - oc create secret -n $NAMESPACE docker-registry llle-project --docker-server=$CI_REGISTRY --docker-username=llle-project --docker-password=$READ_REGISTRY_TOKEN --dry-run=client -o yaml | oc apply -f -
+    - oc create secret -n $NAMESPACE docker-registry forge-secret --docker-server=$CI_REGISTRY --docker-username=read_registry --docker-password=$READ_REGISTRY_TOKEN --dry-run=client -o yaml | oc apply -f -
 
     - oc apply -f k8s/secrets
     - oc apply -f k8s/deployments
diff --git a/Dockerfile b/Dockerfile
index f4efa81e01e91845d2e5aa036ec955ad556f9561..a79e9e97b6e1fbd65d0cdb7269c8494754e024e6 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -48,7 +48,7 @@ RUN chown -Rf "${UID}" ./*
 ##############################
 # STEP 2 build a small image #
 ##############################
-FROM curlimages/curl:8.00.1
+FROM curlimages/curl:8.11.0
 
 WORKDIR /app
 
diff --git a/go.mod b/go.mod
index 1476d8bb39a7f7e0e3901a5c179b45e628673c20..c6eb4521782396720aacfeb7e0fefb89d5421ea2 100644
--- a/go.mod
+++ b/go.mod
@@ -3,12 +3,12 @@ module forge.grandlyon.com/web-et-numerique/factory/llle_project/backoffice-serv
 go 1.18
 
 require (
-	github.com/go-chi/chi/v5 v5.0.11
+	github.com/go-chi/chi/v5 v5.1.0
 	github.com/google/uuid v1.5.0
 	golang.org/x/oauth2 v0.16.0
-	gorm.io/driver/mysql v1.5.2
+	gorm.io/driver/mysql v1.5.7
 	gorm.io/driver/sqlite v1.5.4
-	gorm.io/gorm v1.25.5
+	gorm.io/gorm v1.25.7
 )
 
 require (
diff --git a/go.sum b/go.sum
index b71a4a2954f2b1b2a3d1eb1af0b064af89fba3a8..90b71b9164c299d7f9ab369f28630890dd6243c3 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,7 @@
 github.com/go-chi/chi/v5 v5.0.11 h1:BnpYbFZ3T3S1WMpD79r7R5ThWX40TaFB7L31Y8xqSwA=
 github.com/go-chi/chi/v5 v5.0.11/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
+github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw=
+github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
 github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
 github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
 github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
@@ -52,8 +54,12 @@ google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7
 google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
 gorm.io/driver/mysql v1.5.2 h1:QC2HRskSE75wBuOxe0+iCkyJZ+RqpudsQtqkp+IMuXs=
 gorm.io/driver/mysql v1.5.2/go.mod h1:pQLhh1Ut/WUAySdTHwBpBv6+JKcj+ua4ZFx1QQTBzb8=
+gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo=
+gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
 gorm.io/driver/sqlite v1.5.4 h1:IqXwXi8M/ZlPzH/947tn5uik3aYQslP9BVveoax0nV0=
 gorm.io/driver/sqlite v1.5.4/go.mod h1:qxAuCol+2r6PannQDpOP1FP6ag3mKi4esLnB/jHed+4=
 gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
 gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls=
 gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
+gorm.io/gorm v1.25.7 h1:VsD6acwRjz2zFxGO50gPO6AkNs7KKnvfzUjHQhZDz/A=
+gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
diff --git a/internal/auth/oauth2.go b/internal/auth/oauth2.go
index 423df8eac680bc3d4b740993ceb38eadfb004312..3e9521d0b10237d4744f55c455207f0da3447d09 100644
--- a/internal/auth/oauth2.go
+++ b/internal/auth/oauth2.go
@@ -106,11 +106,11 @@ func (m Manager) HandleOAuth2Callback() http.Handler {
 		}
 		////////////////////////////////////////////////
 		// UNCOMMENT THIS TO DEBUG USERINFO RESPONSE //
-		// readBody, err := ioutil.ReadAll(response.Body)
+		// readBody, err := io.ReadAll(response.Body)
 		// if err != nil {
 		// 	panic(err)
 		// }
-		// newBody := ioutil.NopCloser(bytes.NewBuffer(readBody))
+		// newBody := io.NopCloser(bytes.NewBuffer(readBody))
 		// response.Body = newBody
 		// if string(readBody) != "" {
 		// 	fmt.Printf("BODY : %q \n", readBody)
@@ -126,6 +126,15 @@ func (m Manager) HandleOAuth2Callback() http.Handler {
 			user.Roles[key] = strings.TrimPrefix(strings.Split(role, ",")[0], "CN=")
 		}
 
+		// Filter only allowed roles to reduce the cookie size
+		var filteredRoles []string
+		for _, role := range user.Roles {
+			if role == AdminRole || role == AnimatorRole {
+				filteredRoles = append(filteredRoles, role)
+			}
+		}
+		user.Roles = filteredRoles
+
 		// Check if user has the correct role
 		err = checkUserHasRole(TokenData{User: user}, []string{AdminRole, AnimatorRole})
 
@@ -145,7 +154,7 @@ func (m Manager) HandleOAuth2Callback() http.Handler {
 		}
 		tokenData := TokenData{User: user, XSRFToken: xsrfToken}
 		tokens.CreateCookie(tokenData, m.Hostname, authTokenKey, 24*time.Hour, w)
-		// Log the connexion
+		// Log the connection
 		log.Printf("| %v (%v %v) | Login success | %v", user.Login, user.Name, user.Surname, req.RemoteAddr)
 		// Redirect
 		http.Redirect(w, r, "/", http.StatusFound)
diff --git a/internal/common/common.go b/internal/common/common.go
index 7030f4e3e379847568661da255ba4f04008f8e13..d818a5f54767c691b9701170317d241d018ce2f9 100644
--- a/internal/common/common.go
+++ b/internal/common/common.go
@@ -203,12 +203,6 @@ func PageLimitFromRequest(r *http.Request) (page int, limit int, err error) {
 	if page < 0 {
 		page = 0
 	}
-	switch {
-	case limit > 100:
-		limit = 100
-	case limit < 10:
-		limit = 10
-	}
 	return page, limit, nil
 }
 
diff --git a/internal/models/consent_cleanup.go b/internal/models/consent_cleanup.go
new file mode 100644
index 0000000000000000000000000000000000000000..c7fe21a721cfd6c4c4aa7ae66cfa565603d43653
--- /dev/null
+++ b/internal/models/consent_cleanup.go
@@ -0,0 +1,35 @@
+package models
+
+import (
+	"log"
+	"time"
+)
+
+// deleteOutdatedConsents hard deletes outdated consents where end_date is more than 5 years old
+func deleteOutdatedConsents[T GrdfConsent | SgeConsent](dh *DataHandler, model *T, consentType string) {
+	log.Printf("Running %v outdated consents cleanup", consentType)
+	cutoffDate := time.Now().AddDate(-5, 0, 0)
+
+	result := dh.sqlClient.Unscoped().
+		Where("end_date < ?", cutoffDate).
+		Delete(model)
+
+	log.Printf("nb of rows %v", result.RowsAffected)
+
+	if result.Error != nil {
+		log.Printf("Error deleting outdated %s consents: %v\n", consentType, result.Error)
+		return
+	}
+
+	if result.RowsAffected > 0 {
+		log.Printf("Successfully deleted %d outdated %s consent(s) created before %v\n",
+			result.RowsAffected,
+			consentType,
+			cutoffDate.Format("2006-01-02"))
+	}
+}
+
+func DeleteOutdatedConsents(dh *DataHandler) {
+	deleteOutdatedConsents(dh, &GrdfConsent{}, "GRDF")
+	deleteOutdatedConsents(dh, &SgeConsent{}, "SGE")
+}
diff --git a/internal/rootmux/rootmux_test.go b/internal/rootmux/rootmux_test.go
index 1258e607fea578697c8f1da1d537642032b298cb..15425b948230351a7b4aaefbee0319df27f990db 100644
--- a/internal/rootmux/rootmux_test.go
+++ b/internal/rootmux/rootmux_test.go
@@ -247,7 +247,7 @@ func animatorTests(t *testing.T) {
 		do("GET", "/api/common/monthlyReport?year=2021&month=1", noH, "", http.StatusOK, `{"year":2021,"month":1,"subject":"[Ecolyo] Votre bilan de décembre 2020","info":"Informations du mois","image":"imagebase64","newsTitle":"","newsContent":"","question":"","link":""`)
 
 		// Try to get SGE consents (must fail)
-		do("GET", "/api/admin/consent?limit=50&page=0", xsrfHeader, "", http.StatusForbidden, "no user role among [ANIMATORS OTHER_GROUP] is in allowed roles ([ADMINS])")
+		do("GET", "/api/admin/consent?limit=50&page=0", xsrfHeader, "", http.StatusForbidden, "no user role among [ANIMATORS] is in allowed roles ([ADMINS])")
 	}
 	// Try to login (must pass)
 	do("GET", "/OAuth2Login", noH, "", http.StatusOK, "")
diff --git a/internal/tokens/tokens_test.go b/internal/tokens/tokens_test.go
index 66a24e00b1c9e8006d53f239edaddba8efc91c57..66e4b5cb9bcf6c87e348138034e75c1ac58f136a 100644
--- a/internal/tokens/tokens_test.go
+++ b/internal/tokens/tokens_test.go
@@ -1,7 +1,6 @@
 package tokens
 
 import (
-	"fmt"
 	"testing"
 	"time"
 
@@ -13,10 +12,6 @@ type user struct {
 	Password string
 }
 
-func (u user) String() string {
-	return fmt.Sprintf("Login: %v, Password: %v", u.Login, u.Password)
-}
-
 func TestManagerCreateTokenUnStoreData(t *testing.T) {
 	key, _ := common.GenerateRandomBytes(32)
 	key2, _ := common.GenerateRandomBytes(32)
diff --git a/k8s/README.md b/k8s/README.md
index abd3f1822ce46cb8e4d98b7cb35409cfa2d3deec..948896b4754f4b7dc0bed0471daeff47d3415e5a 100644
--- a/k8s/README.md
+++ b/k8s/README.md
@@ -31,10 +31,10 @@ Configuration:
 - Depuis la console Web, se rendre dans la section "Workloads > Secrets"
 - Cliquer sur le bouton bleu "Create" puis "Image pull secret"
 - Donner les informations :
-  - Secret name : llle-project
+  - Secret name : forge-secret
   - Authentification type : Image registry credentials
   - Registry server address : registry.forge.grandlyon.com
-  - Username: llle-project
+  - Username: read_registry
   - Password: demander le password
 - Cliquer sur Create
 
diff --git a/k8s/deployments/ecolyo-agent-database-deployment.yml b/k8s/deployments/ecolyo-agent-database-deployment.yml
index 9c0d54fe6d3c0e1c65b8c421f50166ee7c63bdf4..fafc676f25301796a1b1f2e7c38b1e71dbd33966 100644
--- a/k8s/deployments/ecolyo-agent-database-deployment.yml
+++ b/k8s/deployments/ecolyo-agent-database-deployment.yml
@@ -40,7 +40,7 @@ spec:
           resources:
             limits:
               cpu: 100m
-              memory: 512Mi
+              memory: 1Gi
             requests:
               cpu: 100m
-              memory: 512Mi
+              memory: 1Gi
diff --git a/k8s/deployments/ecolyo-agent-server-deployment.yml b/k8s/deployments/ecolyo-agent-server-deployment.yml
index 2b733b8b3e045a2a7c9adeccbfb8bfebcd50db3d..c37c1cb5c748def2985cd26dafa9c11c181c0ff0 100644
--- a/k8s/deployments/ecolyo-agent-server-deployment.yml
+++ b/k8s/deployments/ecolyo-agent-server-deployment.yml
@@ -54,4 +54,4 @@ spec:
               cpu: 100m
               memory: 64Mi   
       imagePullSecrets:
-        - name: llle-project
+        - name: forge-secret
diff --git a/k8s/secrets/ecolyo-agent-server-config.yml b/k8s/secrets/ecolyo-agent-server-config.yml
index 8beaebcd8d310d2546c52060152f15e5fa404c80..3f09d2beeddafaacca0ffc78ef761bc944a12510 100644
--- a/k8s/secrets/ecolyo-agent-server-config.yml
+++ b/k8s/secrets/ecolyo-agent-server-config.yml
@@ -20,6 +20,7 @@ stringData:
   BO_API_TOKEN: {{BO_API_TOKEN}}
   TOKEN_URL: {{TOKEN_URL}}
   USERINFO_URL: {{USERINFO_URL}}
+  FETCH_GRDF_TOKEN: {{FETCH_GRDF_TOKEN}}
   GRDF_CLIENT_ID: {{GRDF_CLIENT_ID}}
   GRDF_CLIENT_SECRET: {{GRDF_CLIENT_SECRET}}
 type: Opaque
diff --git a/main.go b/main.go
index baa3d5cb59a1e6ab4a0f15a646020afb2082146a..1ff1d184a5cf90889992b2d1dc6569b67369b207 100644
--- a/main.go
+++ b/main.go
@@ -16,14 +16,15 @@ import (
 )
 
 var (
-	httpsPort  = common.IntValueFromEnv("HTTPS_PORT", 443)     // HTTPS port to serve on
-	debugMode  = common.BoolValueFromEnv("DEBUG_MODE", false)  // Debug mode, disable Secure attribute for cookies
-	mockOAuth2 = common.BoolValueFromEnv("MOCK_OAUTH2", false) // Enable mock OAuth2 login
+	httpsPort      = common.IntValueFromEnv("HTTPS_PORT", 443)         // HTTPS port to serve on
+	debugMode      = common.BoolValueFromEnv("DEBUG_MODE", false)      // Debug mode, disable Secure attribute for cookies
+	mockOAuth2     = common.BoolValueFromEnv("MOCK_OAUTH2", false)     // Enable mock OAuth2 login
+	fetchGrdfToken = common.BoolValueFromEnv("FETCH_GRDF_TOKEN", true) // HTTPS port to serve on
 )
 
 func main() {
 
-	log.Println("--- Server is starting ---")
+	log.Printf("--- Server is starting on port %v ---", httpsPort)
 
 	// Initializations
 	tokens.Init("./mnt/configs/tokenskey.json", debugMode)
@@ -41,19 +42,38 @@ func main() {
 		fmt.Println("Mock OAuth2 server Listening on: http://localhost" + mockOAuth2Port)
 	}
 
-	// Call the function immediately when the server starts
-	models.FetchGRDFAuthAPI()
-
-	// then call GRDF auth api every two hours
-	ticker := time.NewTicker(time.Hour * 2)
 	quit := make(chan struct{})
+
+	// If needed, we shall request a new GRDF token every 2-hours
+	if fetchGrdfToken {
+		// Call the function immediately when the server starts
+		models.FetchGRDFAuthAPI()
+
+		// then call GRDF auth api every two hours
+		ticker := time.NewTicker(time.Hour * 2)
+		go func() {
+			for {
+				select {
+				case <-ticker.C:
+					models.FetchGRDFAuthAPI()
+				case <-quit:
+					ticker.Stop()
+					return
+				}
+			}
+		}()
+	}
+
+	// Deletes outdated consents every 24h
+	dh := models.NewDataHandler()
+	dailyTicker := time.NewTicker(time.Hour * 24)
 	go func() {
 		for {
 			select {
-			case <-ticker.C:
-				models.FetchGRDFAuthAPI()
+			case <-dailyTicker.C:
+				models.DeleteOutdatedConsents(dh)
 			case <-quit:
-				ticker.Stop()
+				dailyTicker.Stop()
 				return
 			}
 		}