diff --git a/bin/account-manager.pl.in b/bin/account-manager.pl.in
index 9fae7917fc2dcc83bf4741b185dad27cae1d6007..7e12682b88cf0531a791b2d5d85ef394f17bc900 100755
--- a/bin/account-manager.pl.in
+++ b/bin/account-manager.pl.in
@@ -254,8 +254,7 @@ sub list_tokens {
         push @{ $args{query} }, token => $options{token};
     }
     if ($options{expired}) {
-        push @{ $args{query} }, creation_date =>
-          { lt => time - ($configuration->{_}->{tokens_validity_period} * 3600) };
+        push @{ $args{query} }, expiration_date => { lt => DateTime->now() };
     }
 
     my $tokens =
@@ -325,12 +324,14 @@ sub add_token {
     }
 
     # compute a new token
+    my $validity_period = $configuration->{_}->{tokens_validity_period};
     my $token = AccountManager::Token->new(
-        db            => $db,
-        email_address => $options{email_address},
-        sp_entityid   => $options{sp_entityid},
-        creation_date => DateTime->today(),
-        token         => AccountManager::Tools::generate_token()
+        db              => $db,
+        email_address   => $options{email_address},
+        sp_entityid     => $options{sp_entityid},
+        creation_date   => DateTime->today(),
+        expiration_date => DateTime->today()->add(hours => $validity_period),
+        token           => AccountManager::Tools::generate_token()
     );
 
     $token->save() or die "failed to save authentication token\n";
diff --git a/conf/create-manager-db.sql b/conf/create-manager-db.sql
index 9c162f1d246e57ef6431b2960a675c5ab16612de..908ab0ea1d80d7ffa8bd5ef15f05ca78b2f95c47 100644
--- a/conf/create-manager-db.sql
+++ b/conf/create-manager-db.sql
@@ -12,6 +12,7 @@ CREATE TABLE `tokens` (
   `email_address` varchar(200) NOT NULL,
   `sp_entityid` varchar(200) NOT NULL,
   `creation_date` date DEFAULT NULL,
+  `expiration_date` date DEFAULT NULL,
   PRIMARY KEY (`id`),
   UNIQUE KEY `token_2` (`token`),
   KEY `token` (`token`),
diff --git a/lib/AccountManager/Token.pm b/lib/AccountManager/Token.pm
index b71c1d9c67beb93e7a51a15a2d265634c4683f17..b44bc5f7f5f09c47b8b8f8eea091b4c6939bf7fd 100644
--- a/lib/AccountManager/Token.pm
+++ b/lib/AccountManager/Token.pm
@@ -9,11 +9,12 @@ __PACKAGE__->meta->setup(
     table   => 'tokens',
 
     columns => [
-        id            => { type => 'bigserial', not_null => 1 },
-        token         => { type => 'varchar', length => 50, not_null => 1 },
-        email_address => { type => 'varchar', length => 200, not_null => 1 },
-        sp_entityid   => { type => 'varchar', length => 200, not_null => 1 },
-        creation_date => { type => 'date' },
+        id              => { type => 'bigserial', not_null => 1 },
+        token           => { type => 'varchar', length => 50, not_null => 1 },
+        email_address   => { type => 'varchar', length => 200, not_null => 1 },
+        sp_entityid     => { type => 'varchar', length => 200, not_null => 1 },
+        creation_date   => { type => 'date' },
+        expiration_date => { type => 'date' },
     ],
 
     primary_key_columns => [ 'id' ],
@@ -29,12 +30,13 @@ sub print {
     $fd = \*STDOUT unless $fd;
 
     printf $fd
-        "Token ID=%s; token=%s; email_address=%s; sp_entityid=%s; creation_date=%s\n",
+        "Token ID=%s; token=%s; email_address=%s; sp_entityid=%s; creation_date=%s; expiration_date=%s\n",
         $self->id(),
         $self->token(),
         $self->email_address(),
         $self->sp_entityid(),
-        $self->creation_date()->strftime('%Y:%m:%d');
+        $self->creation_date()->strftime('%Y:%m:%d'),
+        $self->expiration_date()->strftime('%Y:%m:%d');
 }
 
 1;
diff --git a/lib/AccountManager/WebRequest.pm b/lib/AccountManager/WebRequest.pm
index 27209163d77858ef021ab7d740cf9aa608583db9..2f4cf5492a43fce56dde07976e06f9cfcf34b9ef 100644
--- a/lib/AccountManager/WebRequest.pm
+++ b/lib/AccountManager/WebRequest.pm
@@ -339,12 +339,15 @@ sub req_generate_token {
     }
 
     # compute a new token
+    my $validity_period =
+        $self->{configuration}->{_}->{tokens_validity_period};
     my $token = AccountManager::Token->new(
-        db            => $self->{db},
-        email_address => $self->{in}->{email_address},
-        sp_entityid   => $self->{in}->{sp_entityid},
-        creation_date => DateTime->today(),
-        token         => AccountManager::Tools::generate_token()
+        db              => $self->{db},
+        email_address   => $self->{in}->{email_address},
+        sp_entityid     => $self->{in}->{sp_entityid},
+        creation_date   => DateTime->today(),
+        expiration_date => DateTime->today()->add(hours => $validity_period),
+        token           => AccountManager::Tools::generate_token()
     );
 
     unless ($token->save()) {
diff --git a/t/account-manager.t b/t/account-manager.t
index 498d9b07d36a153a4bfa0f1643f5950c9051e884..5e414c11f3f3df9cb58d44617b2894ac915ab379 100755
--- a/t/account-manager.t
+++ b/t/account-manager.t
@@ -40,6 +40,8 @@ SKIP: {
 
     my $configuration = File::Temp->new(UNLINK => $ENV{TEST_DEBUG} ? 0 : 1);
     print {$configuration} <<EOF;
+tokens_validity_period = 2
+
 [database]
 type = $ENV{TEST_DB_TYPE}
 host = $ENV{TEST_DB_HOST}