diff --git a/book/security.rst b/book/security.rst
index c26108826d2..ef2a0775094 100644
--- a/book/security.rst
+++ b/book/security.rst
@@ -2326,6 +2326,7 @@ Learn more from the Cookbook
* :doc:`Access Control Lists (ACLs) `
* :doc:`/cookbook/security/remember_me`
* :doc:`How to Restrict Firewalls to a Specific Request `
+* :doc:`/cookbook/security/session_expiration`
.. _`FrameworkExtraBundle documentation`: http://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/security.html
.. _`FOSUserBundle`: https://github.com/FriendsOfSymfony/FOSUserBundle
diff --git a/cookbook/map.rst.inc b/cookbook/map.rst.inc
index 24a0cd78371..4820f40a89d 100644
--- a/cookbook/map.rst.inc
+++ b/cookbook/map.rst.inc
@@ -157,6 +157,7 @@
* :doc:`/cookbook/security/target_path`
* :doc:`/cookbook/security/csrf_in_login_form`
* :doc:`/cookbook/security/named_encoders`
+ * :doc:`/cookbook/security/session_expiration`
* **Serializer**
@@ -175,6 +176,7 @@
* :doc:`/cookbook/session/sessions_directory`
* :doc:`/cookbook/session/php_bridge`
* :doc:`/cookbook/session/limit_metadata_writes`
+ * (security) :doc:`/cookbook/security/session_expiration`
* **symfony1**
diff --git a/cookbook/security/index.rst b/cookbook/security/index.rst
index 91f4d654188..d4fedfdd202 100644
--- a/cookbook/security/index.rst
+++ b/cookbook/security/index.rst
@@ -25,3 +25,4 @@ Security
target_path
csrf_in_login_form
named_encoders
+ session_expiration
diff --git a/cookbook/security/session_expiration.rst b/cookbook/security/session_expiration.rst
new file mode 100644
index 00000000000..5abf6c10a7c
--- /dev/null
+++ b/cookbook/security/session_expiration.rst
@@ -0,0 +1,154 @@
+.. index::
+ single: Security; Expiration of Idle Sessions
+
+Expiration of Idle Sessions
+===========================
+
+To be able to expire idle sessions, you have to activate the ``session_expiration``
+firewall listener:
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ # app/config/security.yml
+ security:
+ firewalls:
+ main:
+ # ...
+ session_expiration: ~
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ .. code-block:: php
+
+ // app/config/security.php
+ $container->loadFromExtension('security', array(
+ 'firewalls' => array(
+ 'main'=> array(
+ // ...
+ 'session_expiration' => array(),
+ ),
+ ),
+ ));
+
+To adjust the max idle time before the session is marked as expired, you can
+set the ``max_idle_time`` option value in seconds. By default, the value of this
+option is equal to the ``session.gc_maxlifetime`` configuration option of PHP.
+The ``max_idle_time`` option value **should be less or equal** to the
+``session.gc_maxlifetime`` value.
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ # app/config/security.yml
+ security:
+ firewalls:
+ main:
+ # ...
+ session_expiration:
+ max_idle_time: 600
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ .. code-block:: php
+
+ // app/config/security.php
+ $container->loadFromExtension('security', array(
+ 'firewalls' => array(
+ 'main'=> array(
+ // ...
+ 'session_expiration' => array(
+ 'max_idle_time' => 600,
+ ),
+ ),
+ ),
+ ));
+
+By default, when an expired session is detected, an authorization exception is
+thrown. If the option ``expiration_url`` is set, the user will be redirected
+to this URL and no exception will be thrown:
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ # app/config/security.yml
+ security:
+ firewalls:
+ main:
+ # ...
+ session_expiration:
+ expiration_url: /session-expired
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ .. code-block:: php
+
+ // app/config/security.php
+ $container->loadFromExtension('security', array(
+ 'firewalls' => array(
+ 'main'=> array(
+ // ...
+ 'session_expiration' => array(
+ 'expiration_url' => '/session-expired',
+ ),
+ ),
+ ),
+ ));
+
+To detect idle sessions, the firewall checks the last used timestamp stored in
+the session metadata bag. Beware that this value could be not as accurate as
+expected if you :doc:`limit metadata writes `.