diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 3b3949c0935815dd06dabb31ef4828be15033c4d..c9c2bec414a7395906f242a2f1b1cf6104fc39e1 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -15,19 +15,19 @@ repos:
     -   id: check-merge-conflict
     -   id: check-ast
 -   repo: https://github.com/psf/black
-    rev: 23.3.0
+    rev: 23.7.0
     hooks:
     -   id: black
         files: app
         args: [--check]
 -   repo: https://github.com/PyCQA/flake8
-    rev: 6.0.0
+    rev: 6.1.0
     hooks:
     -   id: flake8
         files: app
         args: [--config=.flake8]
 -   repo: https://github.com/pre-commit/mirrors-mypy
-    rev: v1.2.0
+    rev: v1.4.1
     hooks:
     -   id: mypy
         files: app
diff --git a/app/api/dependencies.py b/app/api/dependencies.py
index c29d19ef85334842d72e86e586d06db65a3066ad..34d91981ae0cec7943a7f915fc2c50055cf87a59 100644
--- a/app/api/dependencies.py
+++ b/app/api/dependencies.py
@@ -51,7 +51,7 @@ async def get_db() -> AsyncGenerator[AsyncSession, None]:
         Async session object with the database
     """
     async with get_async_session(
-        settings.SQLALCHEMY_DATABASE_ASYNC_URI, verbose=settings.SQLALCHEMY_VERBOSE_LOGGER
+        str(settings.SQLALCHEMY_DATABASE_ASYNC_URI), verbose=settings.SQLALCHEMY_VERBOSE_LOGGER
     )() as db:
         yield db
 
@@ -189,7 +189,7 @@ CurrentUser = Annotated[User, Depends(get_current_user)]
 
 async def get_user_by_path_uid(
     uid: str = Path(
-        default=..., description="UID of a user", example="28c5353b8bb34984a8bd4169ba94c606", max_length=64
+        default=..., description="UID of a user", examples=["28c5353b8bb34984a8bd4169ba94c606"], max_length=64
     ),
     db: AsyncSession = Depends(get_db),
 ) -> User:
@@ -219,7 +219,7 @@ async def get_user_by_path_uid(
 
 
 async def get_current_bucket(
-    bucket_name: str = Path(..., description="Name of bucket", example="test-bucket", max_length=63, min_length=3),
+    bucket_name: str = Path(..., description="Name of bucket", examples=["test-bucket"], max_length=63, min_length=3),
     db: AsyncSession = Depends(get_db),
 ) -> Bucket:
     """
diff --git a/app/api/endpoints/buckets.py b/app/api/endpoints/buckets.py
index 949cb530fb6cb9bac77ca1e5a6140ec9c2e8ca1b..83d385dd701f48c14534c447eea7626c0ae12b7d 100644
--- a/app/api/endpoints/buckets.py
+++ b/app/api/endpoints/buckets.py
@@ -329,22 +329,7 @@ async def get_bucket_object(
     db: DBSession,
     current_user: CurrentUser,
     authorization: Authorization,
-    object_path: str = Path(
-        ...,
-        decsription="Name of the object",
-        examples={
-            "normal": {
-                "summary": "Normal file",
-                "description": "A normal file in a bucket",
-                "value": "test.txt",
-            },
-            "pseudo-folder": {
-                "summary": "Pseudo-folder file",
-                "description": "A file in a pseudo folder",
-                "value": "pseudo/sub/folder/test.txt",
-            },
-        },
-    ),
+    object_path: str = Path(..., decsription="Name of the object", examples=["test.txt", "pseudo/sub/folder/test.txt"]),
 ) -> S3ObjectMetaInformation:
     """
     Get the metadata of a specific object in a bucket.\n
diff --git a/app/api/endpoints/s3key.py b/app/api/endpoints/s3key.py
index df0b47616f8321a13aff9571124cb9857f91dfc6..562b05d20a5fdb045c20338ab050935793a0137b 100644
--- a/app/api/endpoints/s3key.py
+++ b/app/api/endpoints/s3key.py
@@ -16,7 +16,7 @@ AccessID = Annotated[
     Path(
         ...,
         description="ID of the S3 access key",
-        example="CRJ6B037V2ZT4U3W17VC",
+        examples=["CRJ6B037V2ZT4U3W17VC"],
     ),
 ]
 
diff --git a/app/ceph/rgw.py b/app/ceph/rgw.py
index d77df5b1b94f78916d81be4cef0396a63ea5f1c1..256b42018307bb789fb6f99bb7be5f7c38d42fea 100644
--- a/app/ceph/rgw.py
+++ b/app/ceph/rgw.py
@@ -12,14 +12,14 @@ else:
 
 s3_resource: S3ServiceResource = resource(
     service_name="s3",
-    endpoint_url=settings.OBJECT_GATEWAY_URI,
+    endpoint_url=str(settings.OBJECT_GATEWAY_URI)[:-1],
     aws_access_key_id=settings.BUCKET_CEPH_ACCESS_KEY,
     aws_secret_access_key=settings.BUCKET_CEPH_SECRET_KEY,
-    verify=settings.OBJECT_GATEWAY_URI.startswith("https"),
+    verify=str(settings.OBJECT_GATEWAY_URI).startswith("https"),
 )
 rgw = RGWAdmin(
     access_key=settings.USER_CEPH_ACCESS_KEY,
     secret_key=settings.USER_CEPH_SECRET_KEY,
-    secure=settings.OBJECT_GATEWAY_URI.startswith("https"),
-    server=settings.OBJECT_GATEWAY_URI.split("://")[-1],
+    secure=str(settings.OBJECT_GATEWAY_URI).startswith("https"),
+    server=str(settings.OBJECT_GATEWAY_URI).split("://")[-1][:-1],
 )
diff --git a/app/check_ceph_connection.py b/app/check_ceph_connection.py
index 5106b509fe4a871f79261f9266973bd615638d4d..71a7cb7d2d2dda71d13efc8deb6560e83814e363 100644
--- a/app/check_ceph_connection.py
+++ b/app/check_ceph_connection.py
@@ -20,7 +20,7 @@ wait_seconds = 2
 )
 def init() -> None:
     try:
-        httpx.get(settings.OBJECT_GATEWAY_URI, timeout=5.0)
+        httpx.get(str(settings.OBJECT_GATEWAY_URI), timeout=5.0)
     except Exception as e:
         logger.error(e)
         raise e
diff --git a/app/check_database_connection.py b/app/check_database_connection.py
index 62db2c5a1b46b37bfcd13abe267efeec942e75e2..ae54e93d69f91628dd1b90245652923206877406 100644
--- a/app/check_database_connection.py
+++ b/app/check_database_connection.py
@@ -22,7 +22,7 @@ wait_seconds = 2
 )
 def init() -> None:
     try:
-        with get_session(url=settings.SQLALCHEMY_DATABASE_NORMAL_URI)() as db:
+        with get_session(url=str(settings.SQLALCHEMY_DATABASE_NORMAL_URI))() as db:
             # Try to create session to check if DB is awake
             db_revision = db.execute(text("SELECT version_num FROM alembic_version LIMIT 1")).scalar_one_or_none()
             if db_revision != latest_revision:
diff --git a/app/core/config.py b/app/core/config.py
index 15c1fffb51c8c20a9f1b4c6c26727c0a6f6b7a9e..87d4d4575c3e360e820ce533c597b37f5016626b 100644
--- a/app/core/config.py
+++ b/app/core/config.py
@@ -1,47 +1,53 @@
 from pathlib import Path
 from typing import Any, Dict, List, Optional, Union
 
-from pydantic import AnyHttpUrl, AnyUrl, BaseSettings, Field, validator
+from pydantic import AnyHttpUrl, AnyUrl, Field, computed_field, field_validator
+from pydantic_settings import BaseSettings, SettingsConfigDict
 
 
 def _assemble_db_uri(values: Dict[str, Any], async_flag: bool = True) -> Any:
     return AnyUrl.build(
         scheme=f"mysql+{'aiomysql' if async_flag else 'pymysql'}",
         password=values.get("DB_PASSWORD"),
-        user=values.get("DB_USER"),
-        port=str(values.get("DB_PORT")),
-        host=values.get("DB_HOST"),
-        path=f"/{values.get('DB_DATABASE') or ''}",
+        username=values.get("DB_USER"),
+        port=values.get("DB_PORT"),
+        host=values.get("DB_HOST"),  # type: ignore[arg-type]
+        path=f"{values.get('DB_DATABASE') or ''}",
     )
 
 
+def _load_public_key(pub_key_val: Optional[str], pub_key_file: Optional[Path]) -> str:
+    pub_key = ""
+    if pub_key_val is not None:
+        pub_key = pub_key_val
+    if pub_key_file is not None:
+        with open(pub_key_file) as f:
+            pub_key = f.read()
+    if len(pub_key) == 0:
+        raise ValueError("PUBLIC_KEY_VALUE or PUBLIC_KEY_FILE must be set")
+    return pub_key
+
+
 class Settings(BaseSettings):
     API_PREFIX: str = Field("/api", description="Path Prefix for all API endpoints.")
 
     public_key_value: str | None = Field(
-        None, description="Public RSA Key in PEM format to sign the JWTs.", env="PUBLIC_KEY_VALUE"
+        None, description="Public RSA Key in PEM format to sign the JWTs.", validation_alias="PUBLIC_KEY_VALUE"
     )
     public_key_file: Path | None = Field(
-        None, description="Path to Public RSA Key in PEM format to sign the JWTs.", env="PUBLIC_KEY_FILE"
+        None, description="Path to Public RSA Key in PEM format to sign the JWTs.", validation_alias="PUBLIC_KEY_FILE"
     )
-    PUBLIC_KEY: str = ""
-
-    @validator("PUBLIC_KEY", pre=True)
-    def load_public_key(cls, v: str, values: Dict[str, Any]) -> str:
-        pub_key = ""
-        if values["public_key_value"] is not None:
-            pub_key = values["public_key_value"]
-        if values["public_key_file"] is not None:
-            with open(values["public_key_file"]) as f:
-                pub_key = f.read()
-        if len(pub_key) == 0:
-            raise ValueError("PUBLIC_KEY_VALUE or PUBLIC_KEY_FILE must be set")
-        return pub_key
+
+    @computed_field  # type: ignore[misc]
+    @property
+    def PUBLIC_KEY(self) -> str:
+        return _load_public_key(self.public_key_value, self.public_key_file)
 
     # BACKEND_CORS_ORIGINS is a JSON-formatted list of origins
     BACKEND_CORS_ORIGINS: List[AnyHttpUrl] = Field([], description="List of all valid CORS origins")
 
-    @validator("BACKEND_CORS_ORIGINS", pre=True)
+    @field_validator("BACKEND_CORS_ORIGINS", mode="before")
+    @classmethod
     def assemble_cors_origins(cls, v: Union[str, List[str]]) -> Union[List[str], str]:
         if isinstance(v, str) and not v.startswith("["):
             return [i.strip() for i in v.split(",")]
@@ -55,21 +61,34 @@ class Settings(BaseSettings):
     DB_DATABASE: str = Field(..., description="Name of the database.")
     DB_PORT: int = Field(3306, description="Port of the database.")
     SQLALCHEMY_VERBOSE_LOGGER: bool = Field(False, description="Flag whether to print the SQL Queries in the logs.")
-    SQLALCHEMY_DATABASE_ASYNC_URI: AnyUrl | None = None
-
-    @validator("SQLALCHEMY_DATABASE_ASYNC_URI", pre=True)
-    def assemble_async_db_connection(cls, v: Optional[str], values: Dict[str, Any]) -> Any:
-        if isinstance(v, str):
-            return v
-        return _assemble_db_uri(values, async_flag=True)
-
-    SQLALCHEMY_DATABASE_NORMAL_URI: AnyUrl | None = None
 
-    @validator("SQLALCHEMY_DATABASE_NORMAL_URI", pre=True)
-    def assemble_db_connection(cls, v: Optional[str], values: Dict[str, Any]) -> Any:
-        if isinstance(v, str):
-            return v
-        return _assemble_db_uri(values, async_flag=False)
+    @computed_field  # type: ignore[misc]
+    @property
+    def SQLALCHEMY_DATABASE_ASYNC_URI(self) -> AnyUrl:
+        return _assemble_db_uri(
+            {
+                "DB_HOST": self.DB_HOST,
+                "DB_USER": self.DB_USER,
+                "DB_PASSWORD": self.DB_PASSWORD,
+                "DB_DATABASE": self.DB_DATABASE,
+                "DB_PORT": self.DB_PORT,
+            },
+            async_flag=True,
+        )
+
+    @computed_field  # type: ignore[misc]
+    @property
+    def SQLALCHEMY_DATABASE_NORMAL_URI(self) -> AnyUrl:
+        return _assemble_db_uri(
+            {
+                "DB_HOST": self.DB_HOST,
+                "DB_USER": self.DB_USER,
+                "DB_PASSWORD": self.DB_PASSWORD,
+                "DB_DATABASE": self.DB_DATABASE,
+                "DB_PORT": self.DB_PORT,
+            },
+            async_flag=False,
+        )
 
     OBJECT_GATEWAY_URI: AnyHttpUrl = Field(..., description="URI of the Ceph Object Gateway.")
     USER_CEPH_ACCESS_KEY: str = Field(
@@ -89,11 +108,7 @@ class Settings(BaseSettings):
     )
     OPA_URI: AnyHttpUrl = Field(..., description="URI of the OPA Service")
     OPA_POLICY_PATH: str = Field("/clowm/authz/allow", description="Path to the OPA Policy for Authorization")
-
-    class Config:
-        case_sensitive = True
-        env_file = ".env"
-        secrets_dir = "/run/secrets"
+    model_config = SettingsConfigDict(case_sensitive=True, env_file=".env", secrets_dir="/run/secrets")
 
 
 settings = Settings()
diff --git a/app/core/security.py b/app/core/security.py
index f34d133aefcc09f58909bdd4204b001bdb7cc61a..60f9fa2f6074b78fdcca0a4c73910d58189f8016 100644
--- a/app/core/security.py
+++ b/app/core/security.py
@@ -54,7 +54,7 @@ async def request_authorization(request_params: AuthzRequest, client: AsyncClien
         Response by the Auth service about the authorization request
     """
     response = await client.post(
-        f"{settings.OPA_URI}/v1/data{settings.OPA_POLICY_PATH}", json={"input": request_params.dict()}
+        f"{settings.OPA_URI}v1/data{settings.OPA_POLICY_PATH}", json={"input": request_params.model_dump()}
     )
 
     parsed_response = AuthzResponse(**response.json())
diff --git a/app/crud/crud_bucket.py b/app/crud/crud_bucket.py
index 7117a557d76213ce357c204792582ae577914931..d069cb9905a90da3ee5f2eb10608d46ff925a4bd 100644
--- a/app/crud/crud_bucket.py
+++ b/app/crud/crud_bucket.py
@@ -161,7 +161,7 @@ class CRUDBucket:
         bucket : clowmdb.models.Bucket | None
             Returns the created bucket. If None then there was a problem, e.g. the name of the bucket is already taken.
         """
-        bucket = Bucket(**bucket_in.dict(), owner_id=uid)
+        bucket = Bucket(**bucket_in.model_dump(), owner_id=uid)
         if await CRUDBucket.get(db, bucket.name) is None:
             db.add(bucket)
             await db.commit()
diff --git a/app/schemas/bucket.py b/app/schemas/bucket.py
index 545a9aa81f66620fbf2ba2b4fa2d801d105103a9..646b6a6b6b50d7c345e7a0b5b23d246ee3f43a73 100644
--- a/app/schemas/bucket.py
+++ b/app/schemas/bucket.py
@@ -1,14 +1,17 @@
+import re
 from datetime import datetime
 from typing import TYPE_CHECKING
 
 from clowmdb.models import Bucket
-from pydantic import BaseModel, Field
+from pydantic import BaseModel, ConfigDict, Field, field_validator
 
 if TYPE_CHECKING:
     from mypy_boto3_s3.service_resource import ObjectSummary
 else:
     ObjectSummary = object
 
+ip_regex = re.compile(r"^((2(5[0-5]|[0-4]\d)|[01]?\d{1,2})\.){3}(2(5[0-5]|[0-4]\d)|[01]?\d{1,2})$")
+
 
 class _BaseBucket(BaseModel):
     """
@@ -17,23 +20,32 @@ class _BaseBucket(BaseModel):
 
     name: str = Field(
         ...,
-        example="test-bucket",
+        examples=["test-bucket"],
         description="Name of the bucket",
         min_length=3,
         max_length=63,
-        regex=r"(?!(^((2(5[0-5]|[0-4]\d)|[01]?\d{1,2})\.){3}(2(5[0-5]|[0-4]\d)|[01]?\d{1,2})$))^[a-z\d][a-z\d.-]{1,61}[a-z\d]$",  # noqa:E501
+        pattern=r"^[a-z\d][a-z\d.-]{1,61}[a-z\d]$",  # noqa:E501
     )
     description: str = Field(
         ...,
-        example="""\
+        examples=[
+            """\
 This is a very long sample description of a bucket and its purpose which has to be more \
 than 126 characters long and is mandatory.
-                             """.strip(),
+                             """.strip()
+        ],
         description="Description of the bucket",
         min_length=126,
         max_length=2**16,
     )
 
+    @field_validator("name")
+    @classmethod
+    def name_is_not_an_ip_address(cls, name: str) -> str:
+        if ip_regex.search(name):
+            raise ValueError("no IP address as bucket name")
+        return name
+
 
 class BucketIn(_BaseBucket):
     """
@@ -48,20 +60,18 @@ class BucketOut(_BaseBucket):
 
     created_at: datetime = Field(
         ...,
-        example=datetime(2022, 1, 1, 0, 0),
+        examples=[datetime(2022, 1, 1, 0, 0)],
         description="Time when the bucket was created",
     )
-    owner: str = Field(..., description="UID of the owner", example="28c5353b8bb34984a8bd4169ba94c606")
-    num_objects: int = Field(..., description="Number of Objects in this bucket", example=6)
-    size: int = Field(..., description="Total size of objects in this bucket in bytes", example=3256216)
+    owner: str = Field(..., description="UID of the owner", examples=["28c5353b8bb34984a8bd4169ba94c606"])
+    num_objects: int = Field(..., description="Number of Objects in this bucket", examples=[6])
+    size: int = Field(..., description="Total size of objects in this bucket in bytes", examples=[3256216])
     owner_constraint: Bucket.Constraint | None = Field(None, description="Constraint for the owner of the bucket")
     description: str = Field(
         ...,
         description="Description of the bucket",
     )
-
-    class Config:
-        orm_mode = True
+    model_config = ConfigDict(from_attributes=True)
 
 
 class S3ObjectMetaInformation(BaseModel):
@@ -72,21 +82,21 @@ class S3ObjectMetaInformation(BaseModel):
     key: str = Field(
         ...,
         description="Key of the Object in the S3 store",
-        example="test.txt",
+        examples=["test.txt"],
         max_length=512,
     )
     bucket: str = Field(
         ...,
         description="Name of the Bucket in which the object is",
-        example="test-bucket",
+        examples=["test-bucket"],
         max_length=256,
     )
-    content_type: str = Field(..., description="MIME type of the object", example="text/plain")
-    size: int = Field(..., description="Size of the object in Bytes", example=123456)
+    content_type: str = Field(..., description="MIME type of the object", examples=["text/plain"])
+    size: int = Field(..., description="Size of the object in Bytes", examples=[123456])
     last_modified: datetime = Field(
         ...,
         description="Last time the object was modified",
-        example=datetime(2022, 1, 1, 0, 0),
+        examples=[datetime(2022, 1, 1, 0, 0)],
     )
 
     @staticmethod
diff --git a/app/schemas/bucket_permission.py b/app/schemas/bucket_permission.py
index 0b738390cf24d696f7e63d8e67a03e89160596b7..b9fcd5fc6ac18be891acf338dff5866a9c06bba6 100644
--- a/app/schemas/bucket_permission.py
+++ b/app/schemas/bucket_permission.py
@@ -12,20 +12,20 @@ class BucketPermissionParameters(BaseModel):
     """
 
     from_timestamp: datetime | None = Field(
-        None, description="Start date of permission", example=datetime(2022, 1, 1, 0, 0)
+        None, description="Start date of permission", examples=[datetime(2022, 1, 1, 0, 0)]
     )
     to_timestamp: datetime | None = Field(
-        None, description="End date of permission", example=datetime(2023, 1, 1, 0, 0)
+        None, description="End date of permission", examples=[datetime(2023, 1, 1, 0, 0)]
     )
-    file_prefix: str | None = Field(None, description="Prefix of subfolder", example="pseudo/sub/folder/")
+    file_prefix: str | None = Field(None, description="Prefix of subfolder", examples=["pseudo/sub/folder/"])
     permission: BucketPermissionDB.Permission | str = Field(
-        BucketPermissionDB.Permission.READ, description="Permission", example=BucketPermissionDB.Permission.READ
+        BucketPermissionDB.Permission.READ, description="Permission", examples=[BucketPermissionDB.Permission.READ]
     )
 
 
 class BucketPermissionIn(BucketPermissionParameters):
-    uid: str = Field(..., description="UID of the grantee", example="28c5353b8bb34984a8bd4169ba94c606")
-    bucket_name: str = Field(..., description="Name of Bucket", example="test-bucket")
+    uid: str = Field(..., description="UID of the grantee", examples=["28c5353b8bb34984a8bd4169ba94c606"])
+    bucket_name: str = Field(..., description="Name of Bucket", examples=["test-bucket"])
 
     def to_hash(self, user_id: str) -> str:
         """
@@ -111,7 +111,7 @@ class BucketPermissionOut(BucketPermissionIn):
     Schema for the bucket permissions.
     """
 
-    grantee_display_name: str = Field(..., description="Display Name of the grantee", example="Bilbo Baggins")
+    grantee_display_name: str = Field(..., description="Display Name of the grantee", examples=["Bilbo Baggins"])
 
     @staticmethod
     def from_db_model(
diff --git a/app/schemas/security.py b/app/schemas/security.py
index 5bd3799182272053553920c247ddf47010b7e177..3c0f596a45e25b0eaa0ea6b86f961733c0d7e3c7 100644
--- a/app/schemas/security.py
+++ b/app/schemas/security.py
@@ -9,7 +9,7 @@ class AuthzResponse(BaseModel):
     decision_id: str = Field(
         ...,
         description="Decision ID for for the specific decision",
-        example="8851dce0-7546-4e81-a89d-111cbec376c1",
+        examples=["8851dce0-7546-4e81-a89d-111cbec376c1"],
     )
     result: bool = Field(..., description="Result of the Authz request")
 
@@ -17,9 +17,9 @@ class AuthzResponse(BaseModel):
 class AuthzRequest(BaseModel):
     """Schema for a Request to OPA"""
 
-    uid: str = Field(..., description="UID of user", example="28c5353b8bb34984a8bd4169ba94c606")
-    operation: str = Field(..., description="Operation the user wants to perform", example="read")
-    resource: str = Field(..., description="Resource the operation should be performed on", example="bucket")
+    uid: str = Field(..., description="UID of user", examples=["28c5353b8bb34984a8bd4169ba94c606"])
+    operation: str = Field(..., description="Operation the user wants to perform", examples=["read"])
+    resource: str = Field(..., description="Resource the operation should be performed on", examples=["bucket"])
 
 
 class JWT(BaseModel):
diff --git a/app/schemas/user.py b/app/schemas/user.py
index dac6d13416b9f3bae38c8facb2478b762b6a900e..c9ca4704b89afe36a3ac3ece46224fc908927d78 100644
--- a/app/schemas/user.py
+++ b/app/schemas/user.py
@@ -6,10 +6,12 @@ class S3Key(BaseModel):
     Schema for a S3 key associated with a user.
     """
 
-    user: str = Field(..., description="UID of the user of that access key", example="28c5353b8bb34984a8bd4169ba94c606")
-    access_key: str = Field(..., description="ID of the S3 access key", example="CRJ6B037V2ZT4U3W17VC")
+    user: str = Field(
+        ..., description="UID of the user of that access key", examples=["28c5353b8bb34984a8bd4169ba94c606"]
+    )
+    access_key: str = Field(..., description="ID of the S3 access key", examples=["CRJ6B037V2ZT4U3W17VC"])
     secret_key: str = Field(
         ...,
         description="Secret of the S3 access key",
-        example="2F5uNTI1qvt4oAroXV0wWct8rWclL2QvFXKqSqjS",
+        examples=["2F5uNTI1qvt4oAroXV0wWct8rWclL2QvFXKqSqjS"],
     )
diff --git a/app/tests/api/test_bucket_permissions.py b/app/tests/api/test_bucket_permissions.py
index 567ad256b2b24e8b924576968ef86d4bd06ed14b..65e3605643aa3058cfb5c2ce69153e29930f6861 100644
--- a/app/tests/api/test_bucket_permissions.py
+++ b/app/tests/api/test_bucket_permissions.py
@@ -269,7 +269,7 @@ class TestBucketPermissionRoutesCreate(_TestBucketPermissionRoutes):
             Random bucket for testing. pytest fixture.
         """
         permission = BucketPermissionSchema(bucket_name=random_bucket.name, uid="ImpossibleUser")
-        response = await client.post(self.base_path, headers=random_user.auth_headers, json=permission.dict())
+        response = await client.post(self.base_path, headers=random_user.auth_headers, json=permission.model_dump())
         assert response.status_code == status.HTTP_404_NOT_FOUND
 
     @pytest.mark.asyncio
@@ -291,7 +291,7 @@ class TestBucketPermissionRoutesCreate(_TestBucketPermissionRoutes):
             Random bucket for testing. pytest fixture.
         """
         permission = BucketPermissionSchema(bucket_name=random_bucket.name, uid=random_user.user.uid)
-        response = await client.post(self.base_path, headers=random_user.auth_headers, json=permission.dict())
+        response = await client.post(self.base_path, headers=random_user.auth_headers, json=permission.model_dump())
         assert response.status_code == status.HTTP_400_BAD_REQUEST
 
     @pytest.mark.asyncio
@@ -316,7 +316,7 @@ class TestBucketPermissionRoutesCreate(_TestBucketPermissionRoutes):
         permission = BucketPermissionSchema(
             bucket_name=random_bucket_permission_schema.bucket_name, uid=random_bucket_permission_schema.uid
         )
-        response = await client.post(self.base_path, headers=random_user.auth_headers, json=permission.dict())
+        response = await client.post(self.base_path, headers=random_user.auth_headers, json=permission.model_dump())
         assert response.status_code == status.HTTP_400_BAD_REQUEST
 
     @pytest.mark.asyncio
@@ -340,7 +340,9 @@ class TestBucketPermissionRoutesCreate(_TestBucketPermissionRoutes):
         """
         permission = BucketPermissionSchema(bucket_name=random_bucket.name, uid=random_second_user.user.uid)
 
-        response = await client.post(self.base_path, headers=random_second_user.auth_headers, json=permission.dict())
+        response = await client.post(
+            self.base_path, headers=random_second_user.auth_headers, json=permission.model_dump()
+        )
         assert response.status_code == status.HTTP_403_FORBIDDEN
 
     @pytest.mark.asyncio
@@ -367,7 +369,7 @@ class TestBucketPermissionRoutesCreate(_TestBucketPermissionRoutes):
         """
         permission = BucketPermissionSchema(bucket_name=random_bucket.name, uid=random_second_user.user.uid)
 
-        response = await client.post(self.base_path, headers=random_user.auth_headers, json=permission.dict())
+        response = await client.post(self.base_path, headers=random_user.auth_headers, json=permission.model_dump())
         assert response.status_code == status.HTTP_201_CREATED
         created_permission = response.json()
         assert created_permission["uid"] == random_second_user.user.uid
@@ -406,7 +408,7 @@ class TestBucketPermissionRoutesCreate(_TestBucketPermissionRoutes):
         await db.commit()
         permission = BucketPermissionSchema(bucket_name=random_bucket.name, uid=random_second_user.user.uid)
 
-        response = await client.post(self.base_path, headers=random_user.auth_headers, json=permission.dict())
+        response = await client.post(self.base_path, headers=random_user.auth_headers, json=permission.model_dump())
         assert response.status_code == status.HTTP_403_FORBIDDEN
 
 
@@ -568,7 +570,7 @@ class TestBucketPermissionRoutesUpdate(_TestBucketPermissionRoutes):
         response = await client.put(
             f"{self.base_path}/bucket/{random_bucket_permission_schema.bucket_name}/user/{random_bucket_permission_schema.uid}",  # noqa:E501
             headers=random_user.auth_headers,
-            content=json.dumps(new_params.dict(), default=json_datetime_converter),
+            content=json.dumps(new_params.model_dump(), default=json_datetime_converter),
         )
         assert response.status_code == status.HTTP_200_OK
         updated_permission = response.json()
@@ -604,7 +606,7 @@ class TestBucketPermissionRoutesUpdate(_TestBucketPermissionRoutes):
         response = await client.put(
             f"{self.base_path}/bucket/{random_bucket_permission_schema.bucket_name}/user/impossibleUser",
             headers=random_user.auth_headers,
-            json=new_params.dict(),
+            json=new_params.model_dump(),
         )
         assert response.status_code == status.HTTP_404_NOT_FOUND
 
@@ -635,7 +637,7 @@ class TestBucketPermissionRoutesUpdate(_TestBucketPermissionRoutes):
         response = await client.put(
             f"{self.base_path}/bucket/{random_bucket.name}/user/{random_second_user.user.uid}",
             headers=random_user.auth_headers,
-            json=new_params.dict(),
+            json=new_params.model_dump(),
         )
         assert response.status_code == status.HTTP_404_NOT_FOUND
 
@@ -665,7 +667,7 @@ class TestBucketPermissionRoutesUpdate(_TestBucketPermissionRoutes):
         response = await client.put(
             f"{self.base_path}/bucket/{random_bucket_permission_schema.bucket_name}/user/{random_second_user.user.uid}",
             headers=random_second_user.auth_headers,
-            json=new_params.dict(),
+            json=new_params.model_dump(),
         )
         assert response.status_code == status.HTTP_403_FORBIDDEN
 
@@ -695,6 +697,6 @@ class TestBucketPermissionRoutesUpdate(_TestBucketPermissionRoutes):
         response = await client.put(
             f"{self.base_path}/bucket/{random_bucket_permission_schema.bucket_name}/user/{random_bucket_permission_schema.uid}",  # noqa:E501
             headers=random_third_user.auth_headers,
-            json=new_params.dict(),
+            json=new_params.model_dump(),
         )
         assert response.status_code == status.HTTP_403_FORBIDDEN
diff --git a/app/tests/api/test_buckets.py b/app/tests/api/test_buckets.py
index b848fa988a5aa7a489dee3706c497d4ca2011986..b6bba3f870aa9d624cba127f401c91dd65c34e75 100644
--- a/app/tests/api/test_buckets.py
+++ b/app/tests/api/test_buckets.py
@@ -159,7 +159,7 @@ class TestBucketRoutesCreate(_TestBucketRoutes):
             Random user for testing. pytest fixture.
         """
         bucket_info = BucketIn(name=random_lower_string(), description=random_lower_string(127))
-        response = await client.post(self.base_path, headers=random_user.auth_headers, json=bucket_info.dict())
+        response = await client.post(self.base_path, headers=random_user.auth_headers, json=bucket_info.model_dump())
 
         assert response.status_code == status.HTTP_201_CREATED
         bucket = response.json()
@@ -194,7 +194,7 @@ class TestBucketRoutesCreate(_TestBucketRoutes):
             Random user for testing. pytest fixture.
         """
         bucket_info = BucketIn(name=random_bucket.name, description=random_lower_string(127))
-        response = await client.post(self.base_path, headers=random_user.auth_headers, json=bucket_info.dict())
+        response = await client.post(self.base_path, headers=random_user.auth_headers, json=bucket_info.model_dump())
 
         assert response.status_code == status.HTTP_400_BAD_REQUEST
 
diff --git a/app/tests/conftest.py b/app/tests/conftest.py
index dfd4bc0f80e6a31549dd798307a0082568d695db..8f1e4883fa9cbe9dbe8d3177897f2d4ce755bee7 100644
--- a/app/tests/conftest.py
+++ b/app/tests/conftest.py
@@ -73,10 +73,10 @@ async def client(mock_rgw_admin: MockRGWAdmin, mock_s3_service: MockS3ServiceRes
     async def get_mock_httpx_client() -> AsyncGenerator[httpx.AsyncClient, None]:
         def mock_request_handler(request: httpx.Request) -> httpx.Response:
             response_body = {}
-            if str(request.url).startswith(settings.OPA_URI):
+            if str(request.url).startswith(str(settings.OPA_URI)):
                 response_body = AuthzResponse(
                     result=not request_admin_permission(request), decision_id=str(uuid4())
-                ).dict()
+                ).model_dump()
             return httpx.Response(200, json=response_body)
 
         async with httpx.AsyncClient(transport=httpx.MockTransport(mock_request_handler)) as http_client:
@@ -97,7 +97,7 @@ async def db() -> AsyncGenerator[AsyncSession, None]:
     Fixture for creating a database session to connect to.
     """
     async with get_async_session(
-        url=settings.SQLALCHEMY_DATABASE_ASYNC_URI, verbose=settings.SQLALCHEMY_VERBOSE_LOGGER
+        url=str(settings.SQLALCHEMY_DATABASE_ASYNC_URI), verbose=settings.SQLALCHEMY_VERBOSE_LOGGER
     )() as dbSession:
         yield dbSession
 
diff --git a/requirements-dev.txt b/requirements-dev.txt
index 74dd93e9bc34a77ef1f4afcd2d507dafe2663dc1..e750f64bada01ec1e85e00175fa4efe2de0b9771 100644
--- a/requirements-dev.txt
+++ b/requirements-dev.txt
@@ -1,18 +1,18 @@
 # test packages
-pytest>=7.3.0,<7.4.0
+pytest>=7.4.0,<7.5.0
 pytest-asyncio>=0.21.0,<0.22.0
-pytest-cov>=4.0.0,<4.1.0
+pytest-cov>=4.1.0,<4.2.0
 coverage[toml]>=7.2.0,<7.3.0
 # Linters
-flake8>=6.0.0,<6.1.0
-autoflake>=2.1.0,<2.2.0
-black>=23.03.0,<23.04.0
+flake8>=6.1.0,<6.2.0
+autoflake>=2.2.0,<2.3.0
+black>=23.07.0,<23.08.0
 isort>=5.12.0,<5.13.0
-mypy>=1.2.0,<1.3.0
+mypy>=1.4.0,<1.5.0
 # stubs for mypy
-boto3-stubs-lite[s3]>=1.26.0,<1.27.0
+boto3-stubs-lite[s3]>=1.28.0,<1.29.0
 sqlalchemy2-stubs
 types-requests
 # Miscellaneous
-pre-commit>=3.2.0,<3.3.0
+pre-commit>=3.3.0,<3.4.0
 python-dotenv
diff --git a/requirements.txt b/requirements.txt
index c22a45c761a4c6d22e2f1e4a637328e8fb75ec79..0eefe6d9249b16065ed6088068841621d319de90 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -2,10 +2,11 @@
 clowmdb>=1.3.0,<1.4.0
 
 # Webserver packages
-anyio>=3.6.0,<3.7.0
-fastapi>=0.95.0,<0.96.0
-pydantic>=1.10.0,<2.0.0
-uvicorn>=0.21.0,<0.22.0
+anyio>=3.7.0,<3.8.0
+fastapi>=0.100.0,<0.101.0
+pydantic>=2.1.0,<2.2.0
+pydantic-settings>=2.0.0
+uvicorn>=0.23.0,<0.24.0
 # Database packages
 PyMySQL>=1.0.2,<1.1.0
 SQLAlchemy>=1.4.0,<2.0.0
@@ -13,7 +14,7 @@ aiomysql>=0.1.0,<0.2.0
 # Security packages
 authlib>=1.2.0,<1.3.0
 # Ceph and S3 packages
-boto3>=1.26.0,<1.27.0
+boto3>=1.28.0,<1.29.0
 rgwadmin>=2.4.0,<2.5.0
 # Miscellaneous
 tenacity>=8.1.0,<8.2.0