diff --git a/.editorconfig b/.editorconfig
index 5b3ad04..55aff3e 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -2,3 +2,4 @@
 
 # MA0003: Add argument name to improve readability
 dotnet_diagnostic.MA0003.severity = none
+csharp_style_prefer_switch_expression=false:suggestion
diff --git a/Borepin.sln b/Borepin.sln
index 01728c9..922d82c 100644
--- a/Borepin.sln
+++ b/Borepin.sln
@@ -31,6 +31,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
 	ProjectSection(SolutionItems) = preProject
 		.editorconfig = .editorconfig
 		.gitlab-ci.yml = .gitlab-ci.yml
+		.gitmodules = .gitmodules
 	EndProjectSection
 EndProject
 Global
diff --git a/Borepin/Borepin/Model/MachineVisualize.cs b/Borepin/Borepin/Model/MachineVisualize.cs
index d04dd9b..c1011ab 100644
--- a/Borepin/Borepin/Model/MachineVisualize.cs
+++ b/Borepin/Borepin/Model/MachineVisualize.cs
@@ -30,7 +30,7 @@ namespace Borepin.Model
             Manager = new UserVisualize(_Machine.Manager);
             Manager.LoadData();
 
-            MachineInfoExtended machineInfoExtended = (await _Machine.Info.GetMachineInfoExtended().ConfigureAwait(false)).Item1;
+            MachineInfoExtended machineInfoExtended = await _Machine.Manage.GetMachineInfoExtended().ConfigureAwait(false);
             if(machineInfoExtended != null)
             {
                 if (machineInfoExtended.CurrentUser == null || machineInfoExtended.CurrentUser.Username == null)
@@ -43,13 +43,13 @@ namespace Borepin.Model
                     CurrentUser.LoadData();
                 }
 
-                if (machineInfoExtended.TransferUser == null || machineInfoExtended.TransferUser.Username == null)
+                if (machineInfoExtended.LastUser == null || machineInfoExtended.LastUser.Username == null)
                 {
                     LastUser = null;
                 }
                 else
                 {
-                    LastUser = new UserVisualize(machineInfoExtended.TransferUser);
+                    LastUser = new UserVisualize(machineInfoExtended.LastUser);
                     LastUser.LoadData();
                 }
             }
@@ -61,7 +61,7 @@ namespace Borepin.Model
 
             CanUse = !((UseInterface_Proxy)_Machine.Use).IsNull;
             CanInUse = !((InUseInterface_Proxy) _Machine.Inuse).IsNull;
-            CanTransfer = !((TransferInterface_Proxy) _Machine.Transfer).IsNull;
+            CanTakeOver = !((TakeoverInterface_Proxy) _Machine.Takeover).IsNull;
             CanCheck = !((CheckInterface_Proxy) _Machine.Check).IsNull;
             CanManage = !((ManageInterface_Proxy) _Machine.Manage).IsNull;
             CanAdmin = !((AdminInterface_Proxy) _Machine.Admin).IsNull;
@@ -140,7 +140,7 @@ namespace Borepin.Model
         }
 
         private bool _CanTransfer;
-        public bool CanTransfer
+        public bool CanTakeOver
         {
             get => _CanTransfer;
             set => SetProperty(ref _CanTransfer, value);
diff --git a/Borepin/Borepin/PageModel/MachineListPageModel.cs b/Borepin/Borepin/PageModel/MachineListPageModel.cs
index 13ff559..d1231d0 100644
--- a/Borepin/Borepin/PageModel/MachineListPageModel.cs
+++ b/Borepin/Borepin/PageModel/MachineListPageModel.cs
@@ -49,10 +49,10 @@ namespace Borepin.PageModel
 
             IsConnected = true;
 
-            IMachineSystem machineSystem = await _BFFHService.GetMachineSystemInterface().ConfigureAwait(false);
+            IMachineSystem machineSystem = (await _BFFHService.GetSession().ConfigureAwait(false)).MachineSystem;
             MachineSystem.IInfoInterface machine_infoInterface = await machineSystem.Info().ConfigureAwait(false);
 
-            IUserSystem userSystem = await _BFFHService.GetUserSystemInterface().ConfigureAwait(false);
+            IUserSystem userSystem = (await _BFFHService.GetSession().ConfigureAwait(false)).UserSystem;
             UserSystem.IInfoInterface user_infoInterface = await userSystem.Info().ConfigureAwait(false);
             User user_self = (await user_infoInterface.GetUserSelf().ConfigureAwait(false)).Item1;
 
@@ -66,7 +66,7 @@ namespace Borepin.PageModel
                 {
                     MachineListItemViewModel new_viewmodel = new MachineListItemViewModel(machine)
                     {
-                        IsUserAssigned = true
+                        IsUserAssigned = true,
                     };
                     viewmodel_list_user_assigned.Add(new_viewmodel);
                 }
@@ -156,10 +156,10 @@ namespace Borepin.PageModel
                     return;
                 }
 
-                IMachineSystem machineInterface = await _BFFHService.GetMachineSystemInterface().ConfigureAwait(false);
+                IMachineSystem machineInterface = (await _BFFHService.GetSession().ConfigureAwait(false)).MachineSystem;
                 MachineSystem.IInfoInterface infoInterface = await machineInterface.Info().ConfigureAwait(false);
 
-                Machine machine = (await infoInterface.GetMachineURN(result.Parameters.GetValue<string>("value")).ConfigureAwait(false)).Item1;
+                Machine machine = await infoInterface.GetMachineURN(result.Parameters.GetValue<string>("value")).ConfigureAwait(false);
 
                 if(machine == null)
                 {
diff --git a/Borepin/Borepin/PageModel/MachinePageModel.cs b/Borepin/Borepin/PageModel/MachinePageModel.cs
index 169e495..8f73a4b 100644
--- a/Borepin/Borepin/PageModel/MachinePageModel.cs
+++ b/Borepin/Borepin/PageModel/MachinePageModel.cs
@@ -43,7 +43,7 @@ namespace Borepin.PageModel
             IMachineSystem machineSystem;
             try
             {
-                machineSystem = await _BFFHService.GetMachineSystemInterface().ConfigureAwait(false);
+                machineSystem = (await _BFFHService.GetSession().ConfigureAwait(false)).MachineSystem;
             }
             catch(ReconnectingFailedException)
             {
@@ -54,7 +54,7 @@ namespace Borepin.PageModel
 
             IInfoInterface info = await machineSystem.Info().ConfigureAwait(false);
 
-            _Machine = (await info.GetMachine(_ID).ConfigureAwait(false)).Item1;
+            _Machine = await info.GetMachine(_ID).ConfigureAwait(false);
             MachineItem = new MachineVisualize(_Machine);
             MachineItem.LoadData();
 
diff --git a/Borepin/Borepin/Service/BFFH/BFFHService.cs b/Borepin/Borepin/Service/BFFH/BFFHService.cs
index 5e767cd..d69d1b5 100644
--- a/Borepin/Borepin/Service/BFFH/BFFHService.cs
+++ b/Borepin/Borepin/Service/BFFH/BFFHService.cs
@@ -8,6 +8,11 @@ using Borepin.Service.Storage;
 using Borepin.Model.Storage;
 using Borepin.Service.BFFH.Exceptions;
 using Borepin.Service.Storage.Exceptions;
+using Capnp.Rpc;
+using FabAccessAPI.Exceptions;
+using System.Security.Cryptography.X509Certificates;
+using System.Net.Security;
+using System.Security.Authentication;
 
 namespace Borepin.Service.BFFH
 {
@@ -59,7 +64,7 @@ namespace Borepin.Service.BFFH
         }
         #endregion
 
-        #region Methods
+        #region Method
         /// <summary>
         /// Get all known Connections from Storage
         /// </summary>
@@ -104,17 +109,16 @@ namespace Borepin.Service.BFFH
         {
             try
             {
-                Capnp.Rpc.TcpRpcClient rpcClient = new Capnp.Rpc.TcpRpcClient();
-                rpcClient.Connect(connection.Address.Host, connection.Address.Port);
-                await rpcClient.WhenConnected.ConfigureAwait(false);
+
+                TcpRpcClient rpcClient = await _ConnectAsync(connection.Address.Host, connection.Address.Port).ConfigureAwait(false);
                 rpcClient.Dispose();
+
+                return true;
             }
             catch
             {
                 return false;
             }
-
-            return true;
         }
 
         /// <summary>
@@ -146,11 +150,11 @@ namespace Borepin.Service.BFFH
 
             try
             {
-                Capnp.Rpc.TcpRpcClient rpcClient = await _ConnectAsync(connection.Address.Host, connection.Address.Port).ConfigureAwait(false);
+                TcpRpcClient rpcClient = await _ConnectAsync(connection.Address.Host, connection.Address.Port).ConfigureAwait(false);
 
                 _APIConnection = new FabAccessAPI.Connection(rpcClient);
             }
-            catch (Capnp.Rpc.RpcException exception) when (string.Equals(exception.Message, "TcpRpcClient is unable to connect", StringComparison.Ordinal))
+            catch (RpcException exception) when (string.Equals(exception.Message, "TcpRpcClient is unable to connect", StringComparison.Ordinal))
             {
                 throw new ConnectingFailedException("Connecting failed", exception);
             }
@@ -185,11 +189,11 @@ namespace Borepin.Service.BFFH
 
             try
             {
-                Capnp.Rpc.TcpRpcClient rpcClient = await _ConnectAsync(connection.Address.Host, connection.Address.Port).ConfigureAwait(false);
+                TcpRpcClient rpcClient = await _ConnectAsync(connection.Address.Host, connection.Address.Port).ConfigureAwait(false);
 
                 _APIConnection = new FabAccessAPI.Connection(rpcClient);
             }
-            catch (Capnp.Rpc.RpcException exception) when (string.Equals(exception.Message, "TcpRpcClient is unable to connect", StringComparison.Ordinal))
+            catch (RpcException exception) when (string.Equals(exception.Message, "TcpRpcClient is unable to connect", StringComparison.Ordinal))
             {
                 throw new ConnectingFailedException("Connecting failed", exception);
             }
@@ -231,11 +235,11 @@ namespace Borepin.Service.BFFH
 
             try
             {
-                Capnp.Rpc.TcpRpcClient rpcClient = await _ConnectAsync(_CurrentConnection.Address.Host, _CurrentConnection.Address.Port).ConfigureAwait(false);
+                TcpRpcClient rpcClient = await _ConnectAsync(_CurrentConnection.Address.Host, _CurrentConnection.Address.Port).ConfigureAwait(false);
 
                 _APIConnection = new FabAccessAPI.Connection(rpcClient);
             }
-            catch (Capnp.Rpc.RpcException exception) when (string.Equals(exception.Message, "TcpRpcClient is unable to connect", StringComparison.Ordinal))
+            catch (RpcException exception) when (string.Equals(exception.Message, "TcpRpcClient is unable to connect", StringComparison.Ordinal))
             {
                 throw new ReconnectingFailedException("Connecting failed", new ConnectingFailedException("Connecting failed", exception));
             }
@@ -264,51 +268,62 @@ namespace Borepin.Service.BFFH
         }
 
         #region FabAccess API Systems
-        public async Task<IMachineSystem> GetMachineSystemInterface()
+        public async Task<Session> GetSession()
         {
             if (!IsConnected)
             {
                 await Reconnect().ConfigureAwait(false);
             }
 
-            return await _APIConnection.AccessMachineSystem().ConfigureAwait(false);
-        }
-
-        public async Task<IUserSystem> GetUserSystemInterface()
-        {
-            if (!IsConnected)
-            {
-                await Reconnect().ConfigureAwait(false);
-            }
-
-            return await _APIConnection.AccessUserSystem().ConfigureAwait(false);
-        }
-
-        public async Task<IPermissionSystem> GetPermissionSystemInterface()
-        {
-            if (!IsConnected)
-            {
-                await Reconnect().ConfigureAwait(false);
-            }
-
-            return await _APIConnection.AccessPermissionSystem().ConfigureAwait(false);
+            return _APIConnection.Session;
         }
         #endregion
         #endregion
 
         #region Private Methods
-        private static async Task<Capnp.Rpc.TcpRpcClient> _ConnectAsync(string host, int port)
+        private static bool RemoteCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
         {
-            Capnp.Rpc.TcpRpcClient rpcClient = new Capnp.Rpc.TcpRpcClient();
+            return true;
+        }
+
+        private async Task<TcpRpcClient> _ConnectAsync(string host, int port)
+        {
+            TcpRpcClient rpcClient = new TcpRpcClient();
+            rpcClient.InjectMidlayer((tcpstream) =>
+            {
+                var sslStream = new SslStream(tcpstream, false, new RemoteCertificateValidationCallback(RemoteCertificateValidationCallback));
+                try
+                {
+                    sslStream.AuthenticateAsClient("bffhd");
+                    return sslStream;
+                }
+                catch (AuthenticationException)
+                {
+                    sslStream.Close();
+                    throw;
+                }
+            });
             rpcClient.Connect(host, port);
             await rpcClient.WhenConnected.ConfigureAwait(false);
 
             return rpcClient;
         }
 
-        private Task<bool> _AuthenticatePlainAsync(string username, string password)
+        private async Task<bool> _AuthenticatePlainAsync(string username, string password)
         {
-            return _APIConnection.Auth("PLAIN", new Dictionary<string, object>(StringComparer.Ordinal) { { "Username", username }, { "Password", password } });
+            try
+            {
+                await _APIConnection.Auth("PLAIN", new Dictionary<string, object>(StringComparer.Ordinal) { { "Username", username }, { "Password", password } }).ConfigureAwait(false);
+                return await Task.FromResult(true).ConfigureAwait(false);
+            }
+            catch(InvalidCredentialsException)
+            {
+                return await Task.FromResult(true).ConfigureAwait(false);
+            }
+            catch (AuthenticatingFailedException)
+            {
+                return await Task.FromResult(true).ConfigureAwait(false);
+            }
         }
         #endregion
     }
diff --git a/Borepin/Borepin/Service/BFFH/IBFFHService.cs b/Borepin/Borepin/Service/BFFH/IBFFHService.cs
index fc4027e..b05d45e 100644
--- a/Borepin/Borepin/Service/BFFH/IBFFHService.cs
+++ b/Borepin/Borepin/Service/BFFH/IBFFHService.cs
@@ -22,8 +22,6 @@ namespace Borepin.Service.BFFH
         Task Disconnect();
 
 
-        Task<IMachineSystem> GetMachineSystemInterface();
-        Task<IPermissionSystem> GetPermissionSystemInterface();
-        Task<IUserSystem> GetUserSystemInterface();
+        Task<Session> GetSession();
     }
 }
\ No newline at end of file
diff --git a/FabAccessAPI/Auth.cs b/FabAccessAPI/Auth.cs
index 1af0cd1..457a091 100644
--- a/FabAccessAPI/Auth.cs
+++ b/FabAccessAPI/Auth.cs
@@ -1,175 +1,81 @@
 using FabAccessAPI.Schema;
 using S22.Sasl;
 using System.Collections.Generic;
-using System.Linq;
 using System.Threading.Tasks;
-using Exception = System.Exception;
+using FabAccessAPI.Exceptions;
+using System.Linq;
 
 namespace FabAccessAPI
 {
-    /// Authentication Identity
-    ///
-    /// Under the hood a string because the form depends heavily on the method
-    public struct AuthCId
-    {
-        public string Id { get; private set; }
-
-        public AuthCId(string id) : this() { Id = id; }
-    }
-
-    /// Authorization Identity
-    ///
-    /// This identity is internal to FabAccess and completely independent from the authentication
-    /// method or source
-    public struct AuthZId
-    {
-        /// Main User ID. Generally an user name or similar
-        public string Uid;
-
-        /// Sub user ID. 
-        ///
-        /// Can change scopes for permissions, e.g. having a +admin account with more permissions than
-        /// the default account and +dashboard et.al. accounts that have restricted permissions for
-        /// their applications
-        public string Subuid;
-
-        /// Realm this account originates.
-        ///
-        /// The Realm is usually described by a domain name but local policy may dictate an unrelated
-        /// mapping
-        public string Realm;
-    }
-
-    /// Authentication/Authorization user object.
-    ///
-    /// This struct contains the user as is passed to the actual authentication/authorization
-    /// subsystems
-    ///
-    public struct AuthUser
-    {
-        /// Contains the Authentication ID used
-        ///
-        /// The authentication ID is an identifier for the authentication exchange. This is different
-        /// than the ID of the user to be authenticated; for example when using x509 the authcid is
-        /// the dn of the certificate, when using GSSAPI the authcid is of form `<userid>@<REALM>`
-        public AuthCId Authcid;
-
-        /// Contains the Authorization ID
-        ///
-        /// This is the identifier of the user to *authenticate as*. This in several cases is different
-        /// to the `authcid`: 
-        /// If somebody wants to authenticate as somebody else, su-style.
-        /// If a person wants to authenticate as a higher-permissions account, e.g. foo may set authzid foo+admin
-        /// to split normal user and "admin" accounts.
-        /// If a method requires a specific authcid that is different from the identifier of the user
-        /// to authenticate as, e.g. GSSAPI, x509 client certificates, API TOKEN authentication.
-        public AuthZId Authzid;
-
-        /// Contains the authentication method used
-        ///
-        /// For the most part this is the SASL method
-        public string AuthMethod;
-
-        /// Method-specific key-value pairs
-        ///
-        /// Each method can use their own key-value pairs.
-        /// E.g. EXTERNAL encodes the actual method used (x509 client certs, UID/GID for unix sockets,
-        /// ...)
-        public Dictionary<string, string> Kvs;
-
-    }
-
-    // Authentication has two parts: Granting the authentication itself and then performing the
-    // authentication.
-    // Granting the authentication checks if 
-    // a) the given authcid fits with the given (authMethod, kvs). In general a failure here indicates
-    //    a programming failure — the authcid come from the same source as that tuple
-    // b) the given authcid may authenticate as the given authzid. E.g. if a given client certificate
-    //    has been configured for that user, if a GSSAPI user maps to a given user, 
-    public enum AuthError
-    {
-        /// Authentication ID is bad/unknown/..
-        BadAuthcid,
-        /// Authorization ID is unknown/..
-        BadAuthzid,
-        /// Authorization ID is not of form user+uid@realm
-        MalformedAuthzid,
-        /// User may not use that authorization id
-        NotAllowedAuthzid,
-
-    }
-
-    public class UnauthorizedException : Exception { }
-    public class UnsupportedMechanismException : Exception { }
-
     /// <summary>
-    /// THIS IS VERY INCOMPLETE!
+    /// Authenticate with SASL
     /// </summary>
     public class Auth
     {
-        #region Log
-        //private static readonly log4net.ILog _Log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+        #region Private Fields
+        private readonly IAuthentication _AuthCap;
         #endregion
 
-        private readonly IAuthenticationSystem _AuthCap;
-        public Auth(IAuthenticationSystem authCap)
+        #region Constructors
+        public Auth(IAuthentication authCap)
         {
             _AuthCap = authCap;
         }
+        #endregion
 
-        public Task<IReadOnlyList<string>> GetMechanisms()
+        #region Methods
+        public async Task<Session> Authenticate(string mech, Dictionary<string, object> properties)
         {
-            return _AuthCap.Mechanisms();
-        }
-
-        public async Task<bool> Authenticate(string mech, Dictionary<string, object> properties)
-        {
-            SaslMechanism? m = SaslFactory.Create(mech);
+            SaslMechanism? saslMechanism = SaslFactory.Create(mech);
             foreach (KeyValuePair<string, object> entry in properties)
             {
-                m.Properties.Add(entry.Key, entry.Value);
+                saslMechanism.Properties.Add(entry.Key, entry.Value);
             }
 
-            Request.initialResponse? initialResponse = new Request.initialResponse();
-            if (m.HasInitial)
+            byte[] data = new byte[0];
+
+            if (saslMechanism.HasInitial)
             {
-                initialResponse.Initial = m.GetResponse(new byte[0]);
+                data = saslMechanism.GetResponse(new byte[0]);
             }
 
-            Request? req = new Request
+            Response? response = await _AuthCap.Step(data);
+            while (!saslMechanism.IsCompleted)
             {
-                Mechanism = m.Name,
-                InitialResponse = initialResponse
-            };
-
-            Response? resp = await _AuthCap.Start(req);
-            while (!m.IsCompleted)
-            {
-                if (resp.which == Response.WHICH.Challence)
+                if(response.Failed != null)
                 {
-                    byte[]? additional = m.GetResponse(resp.Challence.ToArray());
-                    resp = await _AuthCap.Step(additional);
+                    switch (response.Failed.Code)
+                    {
+                        case Response.Error.badMechanism:
+                            throw new BadMechanismException();
+                        case Response.Error.invalidCredentials:
+                            throw new InvalidCredentialsException();
+                        case Response.Error.aborted:
+                        case Response.Error.failed:
+                        default:
+                            throw new AuthenticationFailedException(response.Failed.AdditionalData.ToArray());
+                    }
+                }
+                if(response.Challenge != null)
+                {
+                    byte[]? additional = saslMechanism.GetResponse(response.Challenge.ToArray());
+                    response = await _AuthCap.Step(additional);
                 }
                 else
                 {
-                    break;
+                    throw new AuthenticationFailedException();
                 }
             }
 
-            if (resp.which == Response.WHICH.Outcome)
+            if (response.Successful != null)
             {
-                if (resp.Outcome.Result == Response.Result.successful)
-                {
-                    return true;
-                }
-                else
-                {
-                    //TODO: Provide meaningful info about auth failure
-                    return false;
-                }
+                return response.Successful.Session;
+            }
+            else
+            {
+                throw new AuthenticationFailedException();
             }
-
-            return false;
         }
+        #endregion
     }
 }
diff --git a/FabAccessAPI/Connection.cs b/FabAccessAPI/Connection.cs
index c35ee7f..00d9246 100644
--- a/FabAccessAPI/Connection.cs
+++ b/FabAccessAPI/Connection.cs
@@ -1,4 +1,5 @@
 using Capnp.Rpc;
+using FabAccessAPI.Exceptions;
 using FabAccessAPI.Schema;
 using System;
 using System.Collections.Generic;
@@ -24,12 +25,13 @@ namespace FabAccessAPI
         {
             RpcClient = rpcClient;
             _BootstrapCap = RpcClient.GetMain<IBootstrap>();
-            //_Log.Debug($"Done bootstraping API connection.");
         }
         #endregion
 
         #region Fields
         public TcpRpcClient? RpcClient { get; } = null;
+
+        public Session? Session { get; private set; } = null;
         #endregion
 
         #region Methods
@@ -40,48 +42,21 @@ namespace FabAccessAPI
         /// <param name="mech">The desired authentication mechanism</param>
         /// <param name="kvs">Key-Value data specific to the mechanism</param>
         /// <returns></returns>
-        public async Task<bool> Auth(string mech, Dictionary<string, object> kvs, CancellationToken cancellationToken_ = default)
+        public async Task Auth(string mech, Dictionary<string, object> kvs, CancellationToken cancellationToken_ = default)
         {
-            if(_Auth == null)
-            {
-                IAuthenticationSystem? authCap = await _BootstrapCap.AuthenticationSystem(cancellationToken_).ConfigureAwait(false);
-                _Auth = new Auth(authCap);
-            }
-
-            IReadOnlyList<string>? mechs = await _Auth.GetMechanisms();
+            IReadOnlyList<string>? mechs = await _BootstrapCap.Mechanisms();
             if (!mechs.Contains(mech))
             {
                 throw new UnsupportedMechanismException();
             }
 
-            return await _Auth.Authenticate(mech, kvs);
-        }
+            if (_Auth == null)
+            {
+                IAuthentication? authCap = await _BootstrapCap.CreateSession(mech, cancellationToken_).ConfigureAwait(false);
+                _Auth = new Auth(authCap);
+            }
 
-        /// <summary>
-        /// Get a wrapped capability to interact with machines
-        /// </summary>
-        /// <returns>A wrapped capability to interact with machines</returns>
-        public async Task<IMachineSystem> AccessMachineSystem()
-        {
-            return await _BootstrapCap.MachineSystem();
-        }
-
-        /// <summary>
-        /// Get a wrapped capability to interact with users
-        /// </summary>
-        /// <returns>A wrapped capability to interact with users</returns>
-        public async Task<IUserSystem> AccessUserSystem()
-        {
-            return await _BootstrapCap.UserSystem();
-        }
-
-        /// <summary>
-        /// Get a wrapped capability to interact with permissions
-        /// </summary>
-        /// <returns>A wrapped capability to interact with permissions</returns>
-        public async Task<IPermissionSystem> AccessPermissionSystem()
-        {
-            return await _BootstrapCap.PermissionSystem();
+            Session = await _Auth.Authenticate(mech, kvs);
         }
         #endregion
     }
diff --git a/FabAccessAPI/Exceptions/AuthenticationFailedException.cs b/FabAccessAPI/Exceptions/AuthenticationFailedException.cs
new file mode 100644
index 0000000..cef9c6d
--- /dev/null
+++ b/FabAccessAPI/Exceptions/AuthenticationFailedException.cs
@@ -0,0 +1,28 @@
+using System;
+
+namespace FabAccessAPI.Exceptions
+{
+    public class AuthenticationFailedException : Exception
+    {
+        #region Constructors
+        public AuthenticationFailedException(byte[] additionalData = null)
+        {
+            AdditionalData = additionalData;
+        }
+
+        public AuthenticationFailedException(byte[] additionalData, string message) : base(message)
+        {
+            AdditionalData = additionalData;
+        }
+
+        public AuthenticationFailedException(byte[] additionalData, string message, Exception inner) : base(message, inner)
+        {
+            AdditionalData = additionalData;
+        }
+        #endregion
+
+        #region Fields
+        public byte[]? AdditionalData { get; }
+        #endregion
+    }
+}
diff --git a/FabAccessAPI/Exceptions/BadMechanismException.cs b/FabAccessAPI/Exceptions/BadMechanismException.cs
new file mode 100644
index 0000000..087ddbe
--- /dev/null
+++ b/FabAccessAPI/Exceptions/BadMechanismException.cs
@@ -0,0 +1,22 @@
+using System;
+
+namespace FabAccessAPI.Exceptions
+{
+    public class BadMechanismException : Exception
+    {
+        public BadMechanismException()
+        {
+
+        }
+
+        public BadMechanismException(string message) : base(message)
+        {
+
+        }
+
+        public BadMechanismException(string message, Exception inner) : base(message, inner)
+        {
+
+        }
+    }
+}
diff --git a/FabAccessAPI/Exceptions/InvalidCredentialsException.cs b/FabAccessAPI/Exceptions/InvalidCredentialsException.cs
new file mode 100644
index 0000000..3da236e
--- /dev/null
+++ b/FabAccessAPI/Exceptions/InvalidCredentialsException.cs
@@ -0,0 +1,22 @@
+using System;
+
+namespace FabAccessAPI.Exceptions
+{
+    public class InvalidCredentialsException : Exception
+    {
+        public InvalidCredentialsException()
+        {
+
+        }
+
+        public InvalidCredentialsException(string message) : base(message)
+        {
+
+        }
+
+        public InvalidCredentialsException(string message, Exception inner) : base(message, inner)
+        {
+
+        }
+    }
+}
diff --git a/FabAccessAPI/Exceptions/UnsupportedMechanismException.cs b/FabAccessAPI/Exceptions/UnsupportedMechanismException.cs
new file mode 100644
index 0000000..1f62d09
--- /dev/null
+++ b/FabAccessAPI/Exceptions/UnsupportedMechanismException.cs
@@ -0,0 +1,22 @@
+using System;
+
+namespace FabAccessAPI.Exceptions
+{
+    public class UnsupportedMechanismException : Exception
+    {
+        public UnsupportedMechanismException()
+        {
+
+        }
+
+        public UnsupportedMechanismException(string message) : base(message)
+        {
+
+        }
+
+        public UnsupportedMechanismException(string message, Exception inner) : base(message, inner)
+        {
+
+        }
+    }
+}
diff --git a/FabAccessAPI/schema b/FabAccessAPI/schema
index c855646..c9283eb 160000
--- a/FabAccessAPI/schema
+++ b/FabAccessAPI/schema
@@ -1 +1 @@
-Subproject commit c855646a90958ae575d58be074d187acb9f8f4fa
+Subproject commit c9283ebd696ed6dd428a7c3d24820889f7ab4bf3
diff --git a/FabAccessAPI_Test/Connection_Test.cs b/FabAccessAPI_Test/Connection_Test.cs
new file mode 100644
index 0000000..a63149a
--- /dev/null
+++ b/FabAccessAPI_Test/Connection_Test.cs
@@ -0,0 +1,35 @@
+using Capnp.Rpc;
+using FabAccessAPI;
+using NUnit.Framework;
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace FabAccessAPI_Test
+{
+    public class Connection_Test
+    {
+        [TestCase("test.fab-access.org", 59661)]
+        public async Task Connect(string host, int port)
+        {
+            TcpRpcClient tcpRpcClient = new TcpRpcClient();
+            tcpRpcClient.Connect(host, port);
+            await tcpRpcClient.WhenConnected;
+
+            Connection connection = new Connection(tcpRpcClient);
+        }
+
+        [TestCase("test.fab-access.org", 59661, "Testuser", "secret")]
+        public async Task Authenticate_PLAIN(string host, int port, string username, string password)
+        {
+            TcpRpcClient tcpRpcClient = new TcpRpcClient();
+            tcpRpcClient.Connect(host, port);
+            await tcpRpcClient.WhenConnected;
+
+            Connection connection = new Connection(tcpRpcClient);
+            await connection.Auth("PLAIN", new Dictionary<string, object>(StringComparer.Ordinal) { { "Username", username }, { "Password", password } });
+
+            Assert.IsNotNull(connection.Session);
+        }
+    }
+}
\ No newline at end of file
diff --git a/external/capnproto-dotnetcore b/external/capnproto-dotnetcore
index 1ba1b6f..086bbc2 160000
--- a/external/capnproto-dotnetcore
+++ b/external/capnproto-dotnetcore
@@ -1 +1 @@
-Subproject commit 1ba1b6fbe0d9a278445ef7fde7624f218171156b
+Subproject commit 086bbc2497785d2cc63e9252df6f6d3ee7599579