diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a96b83670d1424af8194616a86a806520d81a7ea..9b4a386a3047643db7a24d2ef63b747e397268fc 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -19,7 +19,6 @@ set(lua_sources)
 lua_source(lua_sources lua/init.lua)
 lua_source(lua_sources lua/uuid.lua)
 lua_source(lua_sources lua/digest.lua)
-lua_source(lua_sources lua/session.lua)
 lua_source(lua_sources lua/msgpackffi.lua)
 lua_source(lua_sources lua/console.lua)
 lua_source(lua_sources lua/bsdsocket.lua)
@@ -62,7 +61,6 @@ set (common_sources
      iproto.cc
      iproto_constants.cc
      iproto_port.cc
-     session.cc
      object.cc
      exception.cc
      ipc.cc
@@ -87,7 +85,6 @@ set (common_sources
      lua/trigger.cc
      lua/ipc.cc
      lua/socket.cc
-     lua/session.cc
      lua/cjson.cc
      lua/yaml.cc
      lua/msgpack.cc
diff --git a/src/box/CMakeLists.txt b/src/box/CMakeLists.txt
index 12177aceb0bec7c7db4db5c5d89535f63b76f282..a827e95026c59b53c14fea87538fa6790e496576 100644
--- a/src/box/CMakeLists.txt
+++ b/src/box/CMakeLists.txt
@@ -6,6 +6,7 @@ set(lua_sources)
 lua_source(lua_sources lua/load_cfg.lua)
 lua_source(lua_sources lua/schema.lua)
 lua_source(lua_sources lua/tuple.lua)
+lua_source(lua_sources lua/session.lua)
 set(bin_sources)
 bin_source(bin_sources bootstrap.snap bootstrap.h)
 
@@ -30,6 +31,7 @@ add_library(box
     space.cc
     alter.cc
     schema.cc
+    session.cc
     port.cc
     request.cc
     txn.cc
@@ -51,4 +53,5 @@ add_library(box
     lua/info.cc
     lua/stat.cc
     lua/error.cc
+    lua/session.cc
     ${bin_sources})
diff --git a/src/box/box.cc b/src/box/box.cc
index 65357cb64bf1a7bb229ce62dec7434c3f9a4522a..1a9acebfdab32183854e10f4553cd6f380429ed6 100644
--- a/src/box/box.cc
+++ b/src/box/box.cc
@@ -40,6 +40,7 @@
 #include <tarantool.h>
 #include "tuple.h"
 #include "lua/call.h"
+#include "session.h"
 #include "schema.h"
 #include "engine.h"
 #include "engine_memtx.h"
@@ -342,6 +343,7 @@ box_free(void)
 	recovery_free();
 	engine_shutdown();
 	stat_free();
+	session_free();
 }
 
 static void
@@ -361,6 +363,7 @@ box_init()
 	box_check_config();
 	title("loading", NULL);
 
+	session_init();
 	replication_prefork(cfg_gets("snap_dir"), cfg_gets("wal_dir"));
 	stat_init();
 
diff --git a/src/box/lua/call.cc b/src/box/lua/call.cc
index 7fed303683ba76dee760ce2407def2cc189d7487..87f396fd1947c97006d165beb02e810fc6569035 100644
--- a/src/box/lua/call.cc
+++ b/src/box/lua/call.cc
@@ -35,6 +35,7 @@
 #include "box/lua/space.h"
 #include "box/lua/stat.h"
 #include "box/lua/info.h"
+#include "box/lua/session.h"
 #include "box/tuple.h"
 
 #include "lua/utils.h"
@@ -50,8 +51,8 @@
 #include "box/schema.h"
 
 /* contents of box.lua, misc.lua, box.net.lua respectively */
-extern char schema_lua[], load_cfg_lua[];
-static const char *lua_sources[] = { schema_lua, load_cfg_lua, NULL };
+extern char session_lua[], schema_lua[], load_cfg_lua[];
+static const char *lua_sources[] = { session_lua, schema_lua, load_cfg_lua, NULL };
 
 /*
  * Functions, exported in box_lua.h should have prefix
@@ -545,6 +546,7 @@ box_lua_init(struct lua_State *L)
 	box_lua_space_init(L);
 	box_lua_info_init(L);
 	box_lua_stat_init(L);
+	box_lua_session_init(L);
 
 	/* Load Lua extension */
 	for (const char **s = lua_sources; *s; s++) {
diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua
index 004c3b303ec0bf51169cb5d7b95fa26e8673d958..de5b364ed766a362504141a9dfd7fea890c643d0 100644
--- a/src/box/lua/schema.lua
+++ b/src/box/lua/schema.lua
@@ -1,9 +1,9 @@
 -- schema.lua (internal file)
 --
 local ffi = require('ffi')
-local session = require('session')
 local msgpackffi = require('msgpackffi')
 local fun = require('fun')
+local session = box.session
 local internal = require('box.internal')
 
 local builtin = ffi.C
@@ -726,9 +726,9 @@ box.schema.user.passwd = function(new_password)
     local _user = box.space[box.schema.USER_ID]
     auth_mech_list = {}
     auth_mech_list["chap-sha1"] = box.schema.user.password(new_password)
-    require('session').su('admin')
+    box.session.su('admin')
     _user:update({uid}, {{"=", 5, auth_mech_list}})
-    require('session').su(uid)
+    box.session.su(uid)
 end
 
 box.schema.user.create = function(name, opts)
diff --git a/src/lua/session.cc b/src/box/lua/session.cc
similarity index 96%
rename from src/lua/session.cc
rename to src/box/lua/session.cc
index 61bb15b32b20015eaafe7547b8ee01929ca2f67e..93927fdb095e992b62c407195533c4b79f4a47bf 100644
--- a/src/lua/session.cc
+++ b/src/box/lua/session.cc
@@ -26,7 +26,7 @@
  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#include "lua/session.h"
+#include "session.h"
 #include "lua/utils.h"
 #include "lua/trigger.h"
 #include "box/access.h"
@@ -38,10 +38,11 @@ extern "C" {
 }
 
 #include <fiber.h>
-#include <session.h>
 #include <sio.h>
 
-static const char *sessionlib_name = "session";
+#include "box/session.h"
+
+static const char *sessionlib_name = "box.session";
 
 /**
  * Return a unique monotonic session
@@ -214,7 +215,7 @@ session_storage_cleanup(int sid)
 }
 
 void
-tarantool_lua_session_init(struct lua_State *L)
+box_lua_session_init(struct lua_State *L)
 {
 	static const struct luaL_reg sessionlib[] = {
 		{"id", lbox_session_id},
@@ -228,6 +229,6 @@ tarantool_lua_session_init(struct lua_State *L)
 		{"on_disconnect", lbox_session_on_disconnect},
 		{NULL, NULL}
 	};
-	luaL_register_module(L, sessionlib_name, sessionlib);
+	luaL_register(L, sessionlib_name, sessionlib);
 	lua_pop(L, 1);
 }
diff --git a/src/lua/session.h b/src/box/lua/session.h
similarity index 96%
rename from src/lua/session.h
rename to src/box/lua/session.h
index d6456d59871333118bce13168e855d0fff289e93..eea0d33317b00607edb3974bc01ee293ddc9238a 100644
--- a/src/lua/session.h
+++ b/src/box/lua/session.h
@@ -31,5 +31,5 @@
 struct lua_State;
 
 void
-tarantool_lua_session_init(struct lua_State *L);
+box_lua_session_init(struct lua_State *L);
 #endif /* INCLUDES_TARANTOOL_LUA_SESSION_H */
diff --git a/src/lua/session.lua b/src/box/lua/session.lua
similarity index 91%
rename from src/lua/session.lua
rename to src/box/lua/session.lua
index 62b91bec9a0617a3322ef942d572841086b37b30..23823cab7581b983f90fbb3427a041b196c592cf 100644
--- a/src/lua/session.lua
+++ b/src/box/lua/session.lua
@@ -1,6 +1,6 @@
 -- session.lua
 
-local session = require('session')
+local session = require('box.session')
 
 setmetatable(session, {
     __index = function(tbl, idx)
diff --git a/src/session.cc b/src/box/session.cc
similarity index 100%
rename from src/session.cc
rename to src/box/session.cc
diff --git a/src/session.h b/src/box/session.h
similarity index 100%
rename from src/session.h
rename to src/box/session.h
diff --git a/src/iproto.cc b/src/iproto.cc
index 4ce93b06d8ab5df02591d24dbedd7ada0f5f4782..c4497b74b2161659af4ee9a93c9719f526c788c9 100644
--- a/src/iproto.cc
+++ b/src/iproto.cc
@@ -39,11 +39,11 @@
 #include "fiber.h"
 #include "say.h"
 #include "evio.h"
-#include "session.h"
 #include "scoped_guard.h"
 #include "memory.h"
 #include "msgpuck/msgpuck.h"
 #include "box/replication.h"
+#include "box/session.h"
 #include "third_party/base64.h"
 #include "coio.h"
 
diff --git a/src/lua/console.lua b/src/lua/console.lua
index 62a4c9ae28b416a5e98e85b27eb56a00888b680e..4d410f34a8255bb6bc552f6bc33a03b4ec11dae1 100644
--- a/src/lua/console.lua
+++ b/src/lua/console.lua
@@ -2,7 +2,6 @@
 
 local internal = require('console')
 local formatter = require('yaml')
-local session = require('session')
 local fiber = require('fiber')
 local socket = require('socket')
 local log = require('log')
diff --git a/src/lua/init.cc b/src/lua/init.cc
index c51abe387591a8aeabd7afc3a9542733454451c2..048575cb5b800a01eb9ba3b54974aad49919740f 100644
--- a/src/lua/init.cc
+++ b/src/lua/init.cc
@@ -51,7 +51,6 @@ extern "C" {
 #include "lua/errno.h"
 #include "lua/socket.h"
 #include "lua/bsdsocket.h"
-#include "lua/session.h"
 #include "lua/cjson.h"
 #include "lua/yaml.h"
 #include "lua/msgpack.h"
@@ -68,7 +67,6 @@ struct lua_State *tarantool_L;
 
 /* contents of src/lua/ files */
 extern char uuid_lua[],
-	session_lua[],
 	msgpackffi_lua[],
 	fun_lua[],
 	digest_lua[],
@@ -81,7 +79,6 @@ extern char uuid_lua[],
 
 static const char *lua_sources[] = {
 	init_lua,
-	session_lua,
 	help_lua,
 	NULL
 };
@@ -281,7 +278,6 @@ tarantool_lua_init(const char *tarantool_bin, int argc, char **argv)
 	tarantool_lua_errno_init(L);
 	tarantool_lua_socket_init(L);
 	tarantool_lua_bsdsocket_init(L);
-	tarantool_lua_session_init(L);
 	tarantool_lua_pickle_init(L);
 	luaopen_msgpack(L);
 	lua_pop(L, 1);
diff --git a/src/tarantool.cc b/src/tarantool.cc
index d9ca591089eb6e8cd3fc14305de7798182e63183..9af242d40236c97b41301040489d452df310eff9 100644
--- a/src/tarantool.cc
+++ b/src/tarantool.cc
@@ -57,7 +57,6 @@
 #include "trivia/util.h"
 #include "tt_pthread.h"
 #include "lua/init.h"
-#include "session.h"
 #include "box/box.h"
 #include "scoped_guard.h"
 #include "random.h"
@@ -488,7 +487,6 @@ tarantool_free(void)
 		free(pid_file);
 	}
 
-	session_free();
 	fiber_free();
 	memory_free();
 	random_free();
@@ -614,7 +612,6 @@ main(int argc, char **argv)
 	iobuf_init();
 	coeio_init();
 	signal_init();
-	session_init();
 	tarantool_lua_init(tarantool_bin, main_argc, main_argv);
 
 	bool start_loop = false;
diff --git a/test/app/session.test.lua b/test/app/session.test.lua
index d732eb03f3290318569abb548f4974f862aed252..d885b845ff584442ed63645dc55f09a43460df4a 100755
--- a/test/app/session.test.lua
+++ b/test/app/session.test.lua
@@ -2,7 +2,8 @@
 
 --
 -- Check that Tarantool creates ADMIN session for #! script
--- 
-session = require('session')
-print('session.id()', session.id())
-print('session.uid()', session.uid())
+--
+box.cfg{logger="tarantool.log"}
+print('session.id()', box.session.id())
+print('session.uid()', box.session.uid())
+os.exit(0)
diff --git a/test/box/.box.lua.kate-swp b/test/box/.box.lua.kate-swp
new file mode 100644
index 0000000000000000000000000000000000000000..71f5a354efe1e7395197cb2a22447034950cf7f8
Binary files /dev/null and b/test/box/.box.lua.kate-swp differ
diff --git a/test/box/access.result b/test/box/access.result
index 61a0ad1ad3789e8c78d73d4c4308160902ff4f40..2976824d007c22e7acf1415344908202da16bc3d 100644
--- a/test/box/access.result
+++ b/test/box/access.result
@@ -1,4 +1,4 @@
-session = require('session')
+session = box.session
 ---
 ...
 -- user id for a Lua session is admin - 1
@@ -210,7 +210,7 @@ box.schema.user.drop('testus')
 -- a test case for gh-289
 -- box.schema.user.drop() with cascade doesn't work
 -- ------------------------------------------------------------
-session = require('session')
+session = box.session
 ---
 ...
 box.schema.user.create('uniuser')
diff --git a/test/box/access.test.lua b/test/box/access.test.lua
index 94fb6afd6167f80f30519f087f12bc2378fd66b6..c8319f1a3f8acdfdfad9e3674cdd7617c846eed5 100644
--- a/test/box/access.test.lua
+++ b/test/box/access.test.lua
@@ -1,5 +1,5 @@
 
-session = require('session')
+session = box.session
 -- user id for a Lua session is admin - 1
 session.uid()
 -- extra arguments are ignored
@@ -97,7 +97,7 @@ box.schema.user.drop('testus')
 -- a test case for gh-289
 -- box.schema.user.drop() with cascade doesn't work
 -- ------------------------------------------------------------
-session = require('session')
+session = box.session
 box.schema.user.create('uniuser')
 box.schema.user.grant('uniuser', 'read, write, execute', 'universe')
 session.su('uniuser')
diff --git a/test/box/auth_access.result b/test/box/auth_access.result
index 0308afa85d61ef35a96459537bb0e59b71f2240f..8f16512d6b234ef0adadf63427b7076aff317bef 100644
--- a/test/box/auth_access.result
+++ b/test/box/auth_access.result
@@ -1,4 +1,4 @@
-session = require('session')
+session = box.session
 ---
 ...
 --
diff --git a/test/box/auth_access.test.lua b/test/box/auth_access.test.lua
index 7e4833f8eb1c6ae1ab8450c5f8909c768b71e4d1..33fcac39909548dc29f02950384b3b008b0a07bb 100644
--- a/test/box/auth_access.test.lua
+++ b/test/box/auth_access.test.lua
@@ -1,4 +1,4 @@
-session = require('session')
+session = box.session
 --
 -- Check a double create space
 --
diff --git a/test/box/bad_trigger.result b/test/box/bad_trigger.result
index 7ed20dea803cd9add6f6387813660c3f17eccc2a..f44644d9f8c100cd2fbf57b4bb3d56fcb4847eb2 100644
--- a/test/box/bad_trigger.result
+++ b/test/box/bad_trigger.result
@@ -6,7 +6,7 @@
 function f1() nosuchfunction() end
 ---
 ...
-require('session').on_connect(f1)
+box.session.on_connect(f1)
 ---
 ...
 greeting:  True
@@ -14,6 +14,6 @@ fixheader:  True
 error code 32
 error message:  [string "function f1() nosuchfunction() end"]:1: attempt to call global 'nosuchfunction' (a nil value)
 eof: True
-require('session').on_connect(nil, f1)
+box.session.on_connect(nil, f1)
 ---
 ...
diff --git a/test/box/bad_trigger.test.py b/test/box/bad_trigger.test.py
index f6bbaad7c67f2caed3f02580f589bc4dd65df6ef..ebbed28bf956dc93ef8450aa8bb093c36b635036 100644
--- a/test/box/bad_trigger.test.py
+++ b/test/box/bad_trigger.test.py
@@ -12,7 +12,7 @@ print """
  """
 
 server.admin("function f1() nosuchfunction() end")
-server.admin("require('session').on_connect(f1)")
+server.admin("box.session.on_connect(f1)")
 
 unpacker = msgpack.Unpacker(use_list = False)
 
@@ -39,4 +39,4 @@ print 'error message: ', body[IPROTO_ERROR]
 print 'eof:', len(s.recv(1024)) == 0
 s.close()
 
-server.admin("require('session').on_connect(nil, f1)")
+server.admin("box.session.on_connect(nil, f1)")
diff --git a/test/box/misc.result b/test/box/misc.result
index cc87edfc46dc383cfbbe214d84da93021f0b7fbc..f144c5debf03902a95d1cf37a324d084b26a372d 100644
--- a/test/box/misc.result
+++ b/test/box/misc.result
@@ -24,6 +24,7 @@ t
   - info
   - rollback
   - schema
+  - session
   - slab
   - snapshot
   - space
diff --git a/test/box/session.result b/test/box/session.result
index af631478099bacd1ba669b900eb55ae1771deb64..d9877ea5f0c69a16fa5a2e6137a6b856408bade1 100644
--- a/test/box/session.result
+++ b/test/box/session.result
@@ -1,4 +1,4 @@
-session = require('session')
+session = box.session
 ---
 ...
 fiber = require('fiber')
diff --git a/test/box/session.storage.result b/test/box/session.storage.result
index bdfe0bedfbf62083a4349f810212198cb76f86b9..e3381f5a9e3292be91d900e58381cbe284e17079 100644
--- a/test/box/session.storage.result
+++ b/test/box/session.storage.result
@@ -1,7 +1,7 @@
 print('session.storage')
 ---
 ...
-session = require('session')
+session = box.session
 ---
 ...
 dump = function(data) return "'" .. require('json').encode(data) .. "'" end
diff --git a/test/box/session.storage.test.lua b/test/box/session.storage.test.lua
index c0ec984500f2ee8384be567af78e250325cf2735..7c36cf7c11cfd2361805ccf21b8e389541a6b1b1 100644
--- a/test/box/session.storage.test.lua
+++ b/test/box/session.storage.test.lua
@@ -1,5 +1,5 @@
 print('session.storage')
-session = require('session')
+session = box.session
 
 dump = function(data) return "'" .. require('json').encode(data) .. "'" end
 
diff --git a/test/box/session.test.lua b/test/box/session.test.lua
index 81af9f35936c383d96c044a0fc4c05e77c39af9d..cb4cf2dc9c5706350cb50ef92d7c1f474b26c424 100644
--- a/test/box/session.test.lua
+++ b/test/box/session.test.lua
@@ -1,4 +1,4 @@
-session = require('session')
+session = box.session
 fiber = require('fiber')
 
 space = box.schema.create_space('tweedledum')
diff --git a/test/wal/func_max.result b/test/wal/func_max.result
index 3a0791da4e9d8366197693f916e05b31d46a8e27..88f4d84ab146f3007f77415ea05162831b93704d 100644
--- a/test/wal/func_max.result
+++ b/test/wal/func_max.result
@@ -1,4 +1,4 @@
-session = require('session')
+session = box.session
 ---
 ...
 session.su('admin')
diff --git a/test/wal/func_max.test.lua b/test/wal/func_max.test.lua
index 1ede3870bb839b45110853c5c3ea301cf70cac08..a37ef0b54bddcc6c9d90dc277e120db7fbb8d6a3 100644
--- a/test/wal/func_max.test.lua
+++ b/test/wal/func_max.test.lua
@@ -1,4 +1,4 @@
-session = require('session')
+session = box.session
 session.su('admin')
 --
 -- Check max function limit