diff --git a/app.py b/app.py
index b69248b6ce4e37522af0c0d3ac7d5a5b73a85f06..611bc5a3df73b85dd3957e39e8dd668d08d36cc4 100644
--- a/app.py
+++ b/app.py
@@ -13,10 +13,12 @@ from areas import auth
 from helpers import (
     BadRequest,
     KratosError,
+    HydraError,
     bad_request_error,
     validation_error,
     kratos_error,
     global_error,
+    hydra_error,
 )
 from config import *
 
@@ -30,6 +32,7 @@ app.register_error_handler(Exception, global_error)
 app.register_error_handler(BadRequest, bad_request_error)
 app.register_error_handler(ValidationError, validation_error)
 app.register_error_handler(KratosError, kratos_error)
+app.register_error_handler(HydraError, hydra_error)
 
 jwt = JWTManager(app)
 
diff --git a/areas/auth/auth.py b/areas/auth/auth.py
index af89132cb50aef42e3ebd5c9264711395184ff84..2bfd938dadcfd5c332da1c6349466f96499e0169 100644
--- a/areas/auth/auth.py
+++ b/areas/auth/auth.py
@@ -1,21 +1,26 @@
-from flask import request, jsonify
+from flask import jsonify
 from flask_jwt_extended import create_access_token
 from flask_cors import cross_origin
+from datetime import timedelta
 
 from areas import api_v1
+from config import *
+from helpers import HydraOauth
 
-USERNAME = 'admin'
-PASSWORD = 'admin'
 
-
-@api_v1.route('/login', methods=['POST'])
+@api_v1.route("/login", methods=["POST"])
 @cross_origin()
 def login():
-    username = request.json.get('username')
-    password = request.json.get('password')
+    authorization_url = HydraOauth.authorize()
+    return jsonify({"authorizationUrl": authorization_url})
+
 
-    if username != USERNAME or password != PASSWORD:
-        return jsonify({'errorMessage': 'Invalid username or password'}), 401
+@api_v1.route("/hydra/callback")
+@cross_origin()
+def hydra_callback():
+    token = HydraOauth.get_token()
+    access_token = create_access_token(
+        identity=token, expires_delta=timedelta(days=365)
+    )
 
-    access_token = create_access_token(identity=username)
-    return jsonify({'username': USERNAME, 'access_token': access_token})
+    return jsonify({"access_token": access_token})
diff --git a/config.py b/config.py
index c902400ef85ad2f1e9218d523ac823f70d0d6cfc..22a643fdd397a85b21ffbf7a253850fbfe4f10c7 100644
--- a/config.py
+++ b/config.py
@@ -1,4 +1,8 @@
 import os
 
-SECRET_KEY = os.environ.get('SECRET_KEY')
-KRATOS_URL = os.environ.get('KRATOS_URL')
+SECRET_KEY = os.environ.get("SECRET_KEY")
+KRATOS_URL = os.environ.get("KRATOS_URL")
+HYDRA_CLIENT_ID = os.environ.get("HYDRA_CLIENT_ID")
+HYDRA_CLIENT_SECRET = os.environ.get("HYDRA_CLIENT_SECRET")
+HYDRA_AUTHORIZATION_BASE_URL = os.environ.get("HYDRA_AUTHORIZATION_BASE_URL")
+TOKEN_URL = os.environ.get("TOKEN_URL")
diff --git a/helpers/__init__.py b/helpers/__init__.py
index 67433630fc15347655a98a2916bf24383cea60a7..850101342a219d94b2db78f223c5d9c63ef57e0f 100644
--- a/helpers/__init__.py
+++ b/helpers/__init__.py
@@ -1,2 +1,3 @@
 from .kratos_api import *
 from .error_handler import *
+from .hydra_oauth import *
diff --git a/helpers/error_handler.py b/helpers/error_handler.py
index 69c6c4dc99a2da3d09a70c889d3bfe57fb7dc81a..e6c696f48223bbe7c3502bbdd94abafd64c04012 100644
--- a/helpers/error_handler.py
+++ b/helpers/error_handler.py
@@ -6,6 +6,10 @@ class KratosError(Exception):
     pass
 
 
+class HydraError(Exception):
+    pass
+
+
 class BadRequest(Exception):
     pass
 
@@ -24,11 +28,17 @@ def validation_error(e):
 
 
 def kratos_error(e):
-    message = e.args[0] if e.args else "Failed to contact Kratos."
+    message = "[KratosError] " + e.args[0] if e.args else "Failed to contact Kratos."
+    status_code = e.args[1] if e.args else 500
+    return jsonify({"errorMessage": message}), status_code
+
+
+def hydra_error(e):
+    message = "[HydraError] " + e.args[0] if e.args else "Failed to contact Hydra."
     status_code = e.args[1] if e.args else 500
     return jsonify({"errorMessage": message}), status_code
 
 
 def global_error(e):
     message = str(e)
-    return jsonify({"errorMessage": message})
+    return jsonify({"errorMessage": message}), 500
diff --git a/helpers/hydra_oauth.py b/helpers/hydra_oauth.py
new file mode 100644
index 0000000000000000000000000000000000000000..ea846951b38d519ab04b9151e8bc1cb5babdb124
--- /dev/null
+++ b/helpers/hydra_oauth.py
@@ -0,0 +1,41 @@
+from flask import request, session
+from requests_oauthlib import OAuth2Session
+
+from config import *
+from helpers import HydraError
+
+
+class HydraOauth:
+    SESSION_KEY = "oauth_state"
+
+    @staticmethod
+    def authorize():
+        try:
+            hydra = OAuth2Session(HYDRA_CLIENT_ID)
+            authorization_url, state = hydra.authorization_url(
+                HYDRA_AUTHORIZATION_BASE_URL
+            )
+
+            # State is used to prevent CSRF, keep this for later.
+            session[HydraOauth.SESSION_KEY] = state
+
+            return authorization_url
+        except Exception as err:
+            raise HydraError(str(err), 500)
+
+    @staticmethod
+    def get_token():
+        try:
+            hydra = OAuth2Session(
+                HYDRA_CLIENT_ID, state=session[HydraOauth.SESSION_KEY]
+            )
+            token = hydra.fetch_token(
+                TOKEN_URL,
+                client_secret=HYDRA_CLIENT_SECRET,
+                authorization_response=request.url,
+            )
+
+            session["hydra_token"] = token
+            return token
+        except Exception as err:
+            raise HydraError(str(err), 500)
diff --git a/helpers/kratos_api.py b/helpers/kratos_api.py
index 739f9a03469f2fb4edf51758dad768e30ba9029f..87b1e9d47925c334714a126903a74f470c92fe4b 100644
--- a/helpers/kratos_api.py
+++ b/helpers/kratos_api.py
@@ -18,6 +18,8 @@ class KratosApi:
             res = requests.get("{}{}".format(KRATOS_URL, url))
             KratosApi.__handleError(res)
             return res
+        except KratosError as err:
+            raise err
         except:
             raise KratosError()
 
diff --git a/requirements.txt b/requirements.txt
index 8510b35cb1cb55576a660d10b59c565ef4efb5ab..b346d6dea9d1f4609a85e88895fcdeab5f79a01a 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -17,6 +17,7 @@ jsonschema==4.3.2
 Jinja2==3.0.3
 MarkupSafe==2.0.1
 mypy-extensions==0.4.3
+oauthlib==3.1.1
 pathspec==0.9.0
 platformdirs==2.4.0
 pycparser==2.21
@@ -24,6 +25,7 @@ PyJWT==2.3.0
 pyrsistent==0.18.0
 regex==2021.11.10
 requests==2.26.0
+requests-oauthlib==1.3.0
 six==1.16.0
 tomli==1.2.3
 typing-extensions==4.0.1
diff --git a/run_app.sh b/run_app.sh
index b8f5f497a2c77d27e8cd8890b1ec399f48bd82d4..302f141d3cea3b1145a8a8a8c96e63583dcbcc0c 100755
--- a/run_app.sh
+++ b/run_app.sh
@@ -22,5 +22,8 @@ export FLASK_APP=app.py
 export FLASK_ENV=development
 export SECRET_KEY="e38hq!@0n64g@qe6)5csk41t=ljo2vllog(%k7njnm4b@kh42c"
 export KRATOS_URL="http://127.0.0.1:8000"
-
+export HYDRA_CLIENT_ID="dashboard"
+export HYDRA_CLIENT_SECRET="BrYRtKygtrcwGHviUSqybvFTgfnaZgPh"
+export HYDRA_AUTHORIZATION_BASE_URL="https://sso.init.stackspin.net/oauth2/auth"
+export TOKEN_URL="https://sso.init.stackspin.net/oauth2/token"
 flask run