Use SECRET_ANALYTICS env var, regenerated at each deployment

- New SECRET_ANALYTICS variable replaces kernel.secret for analytics
- Ansible generates a random 32-char secret at each deploy
- Endpoint token and encryption key change with every deployment
- Existing sessions will get new visitor_id after deploy (expected)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Serreau Jovann
2026-03-26 12:27:05 +01:00
parent a139f86b90
commit 98b0b41064
7 changed files with 13 additions and 6 deletions

1
.env
View File

@@ -76,3 +76,4 @@ OAUTH_KEYCLOAK_REALM=e-cosplay
# MAILER_DSN=ses://ACCESS_KEY:SECRET_KEY@default?region=eu-west-1 # MAILER_DSN=ses://ACCESS_KEY:SECRET_KEY@default?region=eu-west-1
# MAILER_DSN=ses+smtp://ACCESS_KEY:SECRET_KEY@default?region=eu-west-1 # MAILER_DSN=ses+smtp://ACCESS_KEY:SECRET_KEY@default?region=eu-west-1
###< symfony/amazon-mailer ### ###< symfony/amazon-mailer ###
SECRET_ANALYTICS=dev_analytics_secret_change_me

View File

@@ -16,3 +16,4 @@ SESSION_HANDLER_DSN=redis://:e_ticket@redis:6379/1
REDIS_CACHE_DSN=redis://:e_ticket@redis:6379/2 REDIS_CACHE_DSN=redis://:e_ticket@redis:6379/2
SMIME_PASSPHRASE=test SMIME_PASSPHRASE=test
ADMIN_EMAIL=contact@test.com ADMIN_EMAIL=contact@test.com
SECRET_ANALYTICS=test_analytics_secret

View File

@@ -21,6 +21,10 @@
set_fact: set_fact:
docker_gid: "{{ docker_sock.stat.gid }}" docker_gid: "{{ docker_sock.stat.gid }}"
- name: Generate analytics secret
set_fact:
analytics_secret: "{{ lookup('password', '/dev/null chars=ascii_lowercase,digits length=32') }}"
tasks: tasks:
- name: Deploy .env.local - name: Deploy .env.local
template: template:

View File

@@ -24,3 +24,4 @@ OAUTH_KEYCLOAK_CLIENT_ID=e-ticket
OAUTH_KEYCLOAK_CLIENT_SECRET=1oLwbhJDNVmGH8CES1OdQtzR7dECOlII OAUTH_KEYCLOAK_CLIENT_SECRET=1oLwbhJDNVmGH8CES1OdQtzR7dECOlII
OAUTH_KEYCLOAK_URL=https://auth.esy-web.dev OAUTH_KEYCLOAK_URL=https://auth.esy-web.dev
OAUTH_KEYCLOAK_REALM=e-cosplay OAUTH_KEYCLOAK_REALM=e-cosplay
SECRET_ANALYTICS={{ analytics_secret }}

View File

@@ -19,13 +19,13 @@ class AnalyticsController extends AbstractController
#[Route('/t/{token}', name: 'app_analytics_track', methods: ['POST'])] #[Route('/t/{token}', name: 'app_analytics_track', methods: ['POST'])]
public function track( public function track(
string $token, string $token,
#[Autowire('%kernel.secret%')] string $appSecret, #[Autowire(env: 'SECRET_ANALYTICS')] string $analyticsSecret,
Request $request, Request $request,
AnalyticsCryptoService $crypto, AnalyticsCryptoService $crypto,
EntityManagerInterface $em, EntityManagerInterface $em,
MessageBusInterface $bus, MessageBusInterface $bus,
): Response { ): Response {
$expectedToken = substr(hash('sha256', $appSecret.'_endpoint'), 0, 8); $expectedToken = substr(hash('sha256', $analyticsSecret.'_endpoint'), 0, 8);
if (!hash_equals($expectedToken, $token)) { if (!hash_equals($expectedToken, $token)) {
return new Response('', 404); return new Response('', 404);
} }

View File

@@ -9,9 +9,9 @@ class AnalyticsCryptoService
private string $key; private string $key;
public function __construct( public function __construct(
#[Autowire('%kernel.secret%')] string $appSecret, #[Autowire(env: 'SECRET_ANALYTICS')] private string $analyticsSecret,
) { ) {
$this->key = substr(hash('sha256', $appSecret.'_analytics', true), 0, 32); $this->key = substr(hash('sha256', $this->analyticsSecret, true), 0, 32);
} }
public function encrypt(array $data): string public function encrypt(array $data): string

View File

@@ -13,9 +13,9 @@ class AnalyticsExtension extends AbstractExtension implements GlobalsInterface
public function __construct( public function __construct(
private AnalyticsCryptoService $crypto, private AnalyticsCryptoService $crypto,
#[Autowire('%kernel.secret%')] string $appSecret, #[Autowire(env: 'SECRET_ANALYTICS')] string $analyticsSecret,
) { ) {
$this->endpointToken = substr(hash('sha256', $appSecret.'_endpoint'), 0, 8); $this->endpointToken = substr(hash('sha256', $analyticsSecret.'_endpoint'), 0, 8);
} }
public function getGlobals(): array public function getGlobals(): array