diff --git a/api-collection/Secret Controller/Fetch all by project and environment.bru b/api-collection/Secret Controller/Fetch all by project and environment.bru
new file mode 100644
index 000000000..649df0499
--- /dev/null
+++ b/api-collection/Secret Controller/Fetch all by project and environment.bru	
@@ -0,0 +1,26 @@
+meta {
+  name: Fetch all by project and environment
+  type: http
+  seq: 5
+}
+
+get {
+  url: {{BASE_URL}}/api/secret/:project_slug/:environment_slug
+  body: none
+  auth: bearer
+}
+
+params:path {
+  project_slug: 
+  environment_slug: 
+}
+
+auth:bearer {
+  token: {{JWT}}
+}
+
+docs {
+  ## Description
+  
+  Fetches all the secrets for a particular pair of project and environment. Used by the CLI to prefetch the existing secrets.
+}
\ No newline at end of file
diff --git a/api-collection/Variable Controller/Fetch all by project and environment.bru b/api-collection/Variable Controller/Fetch all by project and environment.bru
new file mode 100644
index 000000000..6dce34152
--- /dev/null
+++ b/api-collection/Variable Controller/Fetch all by project and environment.bru	
@@ -0,0 +1,26 @@
+meta {
+  name: Fetch all by project and environment
+  type: http
+  seq: 5
+}
+
+get {
+  url: {{BASE_URL}}/api/variable/:project_slug/:environment_slug
+  body: none
+  auth: bearer
+}
+
+params:path {
+  project_slug: project-1-uzukc
+  environment_slug: alpha-l7xvp
+}
+
+auth:bearer {
+  token: {{JWT}}
+}
+
+docs {
+  ## Description
+  
+  Fetches all the variables for a particular pair of project and environment. Used by the CLI to prefetch the existing variables.
+}
\ No newline at end of file
diff --git a/apps/api/jest.e2e-config.ts b/apps/api/jest.e2e-config.ts
index 0f2006243..c853ca443 100644
--- a/apps/api/jest.e2e-config.ts
+++ b/apps/api/jest.e2e-config.ts
@@ -3,7 +3,8 @@ export default {
   forceExit: true,
   displayName: 'api',
   testEnvironment: 'node',
-  testMatch: ['**/*.e2e.spec.ts'],
+  testMatch: ['**/project.e2e.spec.ts'],
+  testTimeout: 10000,
   transform: {
     '^.+\\.[tj]sx?$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }]
   },
diff --git a/apps/api/src/auth/service/authorization.service.ts b/apps/api/src/auth/service/authorization.service.ts
index 0eb439dd7..ddb81c5a1 100644
--- a/apps/api/src/auth/service/authorization.service.ts
+++ b/apps/api/src/auth/service/authorization.service.ts
@@ -7,7 +7,7 @@ import { SecretWithProjectAndVersion } from '@/secret/secret.types'
 import { IntegrationWithWorkspace } from '@/integration/integration.types'
 import { AuthorizationParams } from './authorization.types'
 import { AuthenticatedUser } from '@/user/user.types'
-import { Workspace, User } from '@prisma/client'
+import { Workspace } from '@prisma/client'
 import { PrismaService } from '@/prisma/prisma.service'
 import { CustomLoggerService } from '@/common/logger.service'
 import { InternalServerErrorException, NotFoundException } from '@nestjs/common'
@@ -52,16 +52,24 @@ export class AuthorizationService {
   public async authorizeUserAccessToProject(
     params: AuthorizationParams
   ): Promise<ProjectWithSecrets> {
+    console.log(
+      `${Date.now()}: authorizeUserAccessToProject ${params.entity.slug} - started`
+    )
     const project =
       await this.authorityCheckerService.checkAuthorityOverProject(params)
 
-    const workspace = await this.getWorkspace(
-      params.user.id,
-      project.workspaceId
+    console.log(
+      `${Date.now()}: Project acces authorized ${project.name} WorkspaceId: ${project.workspaceId}`
     )
 
+    const workspace = await this.getWorkspace(project.workspaceId)
+
     this.checkUserHasAccessToWorkspace(params.user, workspace)
 
+    console.log(
+      `${Date.now()}: authorizeUserAccessToProject ${params.entity.slug} - finished`
+    )
+
     return project
   }
 
@@ -80,10 +88,7 @@ export class AuthorizationService {
     const environment =
       await this.authorityCheckerService.checkAuthorityOverEnvironment(params)
 
-    const workspace = await this.getWorkspace(
-      params.user.id,
-      environment.project.workspaceId
-    )
+    const workspace = await this.getWorkspace(environment.project.workspaceId)
 
     this.checkUserHasAccessToWorkspace(params.user, workspace)
 
@@ -105,10 +110,7 @@ export class AuthorizationService {
     const variable =
       await this.authorityCheckerService.checkAuthorityOverVariable(params)
 
-    const workspace = await this.getWorkspace(
-      params.user.id,
-      variable.project.workspaceId
-    )
+    const workspace = await this.getWorkspace(variable.project.workspaceId)
 
     this.checkUserHasAccessToWorkspace(params.user, workspace)
 
@@ -130,10 +132,7 @@ export class AuthorizationService {
     const secret =
       await this.authorityCheckerService.checkAuthorityOverSecret(params)
 
-    const workspace = await this.getWorkspace(
-      params.user.id,
-      secret.project.workspaceId
-    )
+    const workspace = await this.getWorkspace(secret.project.workspaceId)
 
     this.checkUserHasAccessToWorkspace(params.user, workspace)
 
@@ -162,16 +161,12 @@ export class AuthorizationService {
 
   /**
    * Fetches the requested workspace specified by userId and the filter.
-   * @param userId The id of the user
-   * @param filter The filter optionally including the workspace id, slug or name
+   * @param workspaceId The workspace id
    * @returns The requested workspace
    * @throws InternalServerErrorException if there's an error when communicating with the database
    * @throws NotFoundException if the workspace is not found
    */
-  private async getWorkspace(
-    userId: User['id'],
-    workspaceId: Workspace['id']
-  ): Promise<Workspace> {
+  private async getWorkspace(workspaceId: Workspace['id']): Promise<Workspace> {
     let workspace: Workspace
 
     try {
@@ -186,6 +181,15 @@ export class AuthorizationService {
     }
 
     if (!workspace) {
+      console.log(`${Date.now()}: Workspace not found: ${workspaceId}`)
+
+      const workspaces = await this.prisma.workspace.findMany()
+
+      console.log(`${Date.now()}: Workspaces: ${workspaces.length}`)
+      for (const workspace of workspaces) {
+        console.log(`${workspace.name}: ${workspace.id}`)
+      }
+
       throw new NotFoundException(`Workspace ${workspaceId} not found`)
     }
 
diff --git a/apps/api/src/project/project.e2e.spec.ts b/apps/api/src/project/project.e2e.spec.ts
index b984dd623..5cfd75f98 100644
--- a/apps/api/src/project/project.e2e.spec.ts
+++ b/apps/api/src/project/project.e2e.spec.ts
@@ -101,6 +101,7 @@ describe('Project Controller Tests', () => {
   })
 
   beforeEach(async () => {
+    console.log(`${Date.now()}: Set up test data`)
     const createUser1 = await userService.createUser({
       name: 'John Doe',
       email: 'johndoe@keyshade.xyz',
@@ -120,6 +121,9 @@ describe('Project Controller Tests', () => {
     workspace1 = createUser1.defaultWorkspace
     workspace2 = createUser2.defaultWorkspace
 
+    console.log(`${Date.now()}: Workspace 1: ${workspace1.id}`)
+    console.log(`${Date.now()}: Workspace 2: ${workspace2.id}`)
+
     delete createUser1.defaultWorkspace
     delete createUser2.defaultWorkspace
 
@@ -151,11 +155,16 @@ describe('Project Controller Tests', () => {
         'Project for testing if all environments,secrets and keys are being fetched or not',
       storePrivateKey: true
     })) as Project
+    console.log(`${Date.now()}: Test data set up`)
   })
 
   afterEach(async () => {
-    await prisma.user.deleteMany()
-    await prisma.workspace.deleteMany()
+    console.log(`${Date.now()}: Cleaning up test data`)
+    await prisma.$transaction([
+      prisma.user.deleteMany(),
+      prisma.workspace.deleteMany()
+    ])
+    console.log(`${Date.now()}: Test data cleaned up`)
   })
 
   it('should be defined', async () => {
@@ -1126,12 +1135,12 @@ describe('Project Controller Tests', () => {
         user2,
         project3.slug,
         {
-          name: 'Forked Project'
+          name: 'Forked Project 1'
         }
       )) as Project
 
       expect(forkedProject).toBeDefined()
-      expect(forkedProject.name).toBe('Forked Project')
+      expect(forkedProject.name).toBe('Forked Project 1')
       expect(forkedProject.publicKey).toBeDefined()
       expect(forkedProject.privateKey).toBeDefined()
       expect(forkedProject.publicKey).not.toBe(project3.publicKey)
@@ -1147,7 +1156,7 @@ describe('Project Controller Tests', () => {
       })
 
       expect(forkedProjectFromDB).toBeDefined()
-      expect(forkedProjectFromDB.name).toBe('Forked Project')
+      expect(forkedProjectFromDB.name).toBe('Forked Project 1')
       expect(forkedProjectFromDB.publicKey).toBeDefined()
       expect(forkedProjectFromDB.privateKey).toBeDefined()
       expect(forkedProjectFromDB.publicKey).not.toBe(project3.publicKey)
@@ -1162,7 +1171,7 @@ describe('Project Controller Tests', () => {
         method: 'POST',
         url: `/project/123/fork`,
         payload: {
-          name: 'Forked Project'
+          name: 'Forked Project 2'
         },
         headers: {
           'x-e2e-user-email': user2.email
@@ -1177,7 +1186,7 @@ describe('Project Controller Tests', () => {
         method: 'POST',
         url: `/project/${project2.slug}/fork`,
         payload: {
-          name: 'Forked Project'
+          name: 'Forked Project 3'
         },
         headers: {
           'x-e2e-user-email': user1.email
@@ -1192,7 +1201,7 @@ describe('Project Controller Tests', () => {
         user2,
         project3.slug,
         {
-          name: 'Forked Project'
+          name: 'Forked Project 4'
         }
       )) as Project
 
@@ -1208,7 +1217,7 @@ describe('Project Controller Tests', () => {
         user2,
         project3.slug,
         {
-          name: 'Forked Project',
+          name: 'Forked Project 5',
           workspaceSlug: newWorkspace.slug
         }
       )) as Project
@@ -1218,7 +1227,7 @@ describe('Project Controller Tests', () => {
 
     it('should not be able to create a fork with the same name in a workspace', async () => {
       await projectService.createProject(user2, workspace2.slug, {
-        name: 'Forked Project',
+        name: 'Forked Project 6',
         description: 'Forked Project description',
         storePrivateKey: true,
         accessLevel: ProjectAccessLevel.GLOBAL
@@ -1228,7 +1237,7 @@ describe('Project Controller Tests', () => {
         method: 'POST',
         url: `/project/${project3.slug}/fork`,
         payload: {
-          name: 'Forked Project'
+          name: 'Forked Project 6'
         },
         headers: {
           'x-e2e-user-email': user2.email
@@ -1319,7 +1328,7 @@ describe('Project Controller Tests', () => {
         user2,
         project3.slug,
         {
-          name: 'Forked Project'
+          name: 'Forked Project 8'
         }
       )
 
@@ -1446,7 +1455,7 @@ describe('Project Controller Tests', () => {
         user2,
         project3.slug,
         {
-          name: 'Forked Project'
+          name: 'Forked Project 9'
         }
       )
 
@@ -1636,7 +1645,7 @@ describe('Project Controller Tests', () => {
         user2,
         project3.slug,
         {
-          name: 'Forked Project'
+          name: 'Forked Project 10'
         }
       )
 
@@ -1771,7 +1780,7 @@ describe('Project Controller Tests', () => {
         user2,
         project3.slug,
         {
-          name: 'Forked Project'
+          name: 'Forked Project 11'
         }
       )
 
@@ -1798,7 +1807,7 @@ describe('Project Controller Tests', () => {
 
     it('should be able to fetch all forked projects of a project', async () => {
       await projectService.forkProject(user2, project3.slug, {
-        name: 'Forked Project'
+        name: 'Forked Project 12'
       })
 
       const response = await app.inject({
@@ -1827,33 +1836,57 @@ describe('Project Controller Tests', () => {
     })
 
     it('should not contain a forked project that has access level other than GLOBAL', async () => {
-      // Make a hidden fork
-      const hiddenProject = await projectService.forkProject(
-        user2,
-        project3.slug,
-        {
-          name: 'Hidden Forked Project'
-        }
-      )
-      await projectService.updateProject(user2, hiddenProject.slug, {
-        accessLevel: ProjectAccessLevel.INTERNAL
-      })
+      try {
+        console.log(`${Date.now()}: Test started`)
+        console.log(
+          `${Date.now()}: Parent WorkspaceId: ${project3.workspaceId}`
+        )
+        // Make a hidden fork
+        const hiddenProject = await projectService.forkProject(
+          user2,
+          project3.slug,
+          {
+            name: 'Hidden Forked Project'
+          }
+        )
+        await projectService.updateProject(user2, hiddenProject.slug, {
+          accessLevel: ProjectAccessLevel.INTERNAL
+        })
 
-      // Make a public fork
-      await projectService.forkProject(user2, project3.slug, {
-        name: 'Forked Project'
-      })
+        console.log(
+          `${Date.now()}: Internal fork WorkspaceId: ${hiddenProject.workspaceId}`
+        )
 
-      const response = await app.inject({
-        method: 'GET',
-        url: `/project/${project3.slug}/forks`,
-        headers: {
-          'x-e2e-user-email': user1.email
-        }
-      })
+        // Make a public fork
+        const publicProject = await projectService.forkProject(
+          user2,
+          project3.slug,
+          {
+            name: 'Forked Project 13'
+          }
+        )
 
-      expect(response.statusCode).toBe(200)
-      expect(response.json().items).toHaveLength(1)
+        console.log(
+          `${Date.now()}: Public fork WorkspaceId: ${publicProject.workspaceId}`
+        )
+
+        const response = await app.inject({
+          method: 'GET',
+          url: `/project/${project3.slug}/forks`,
+          headers: {
+            'x-e2e-user-email': user1.email
+          }
+        })
+
+        console.log(`${Date.now()}: Get forks response: ${response.json()}`)
+
+        expect(response.statusCode).toBe(200)
+        expect(response.json().items).toHaveLength(1)
+        console.log(`${Date.now()}: Test finished`)
+      } catch (error) {
+        console.error(`${Date.now()}: Error: ${error}`)
+        throw error
+      }
     })
   })
 })
diff --git a/apps/api/src/project/service/project.service.ts b/apps/api/src/project/service/project.service.ts
index 7db44a553..1686569c4 100644
--- a/apps/api/src/project/service/project.service.ts
+++ b/apps/api/src/project/service/project.service.ts
@@ -231,6 +231,7 @@ export class ProjectService {
     projectSlug: Project['slug'],
     dto: UpdateProject
   ) {
+    console.log(`${Date.now()}: updateProject ${projectSlug} - started`)
     // Check if the user has the authority to update the project
     let authority: Authority = Authority.UPDATE_PROJECT
 
@@ -371,6 +372,7 @@ export class ProjectService {
     )
 
     this.log.debug(`Updated project ${updatedProject.id}`)
+    console.log(`${Date.now()}: updateProject ${projectSlug} - finished`)
     return {
       ...updatedProject,
       privateKey,
@@ -394,6 +396,7 @@ export class ProjectService {
     projectSlug: Project['slug'],
     forkMetadata: ForkProject
   ) {
+    console.log(`${Date.now()}: forkProject ${forkMetadata.name} - started`)
     const project =
       await this.authorizationService.authorizeUserAccessToProject({
         user,
@@ -462,7 +465,7 @@ export class ProjectService {
         accessLevel: project.accessLevel,
         isForked: true,
         forkedFromId: project.id,
-        workspaceId: workspaceId,
+        workspaceId,
         lastUpdatedById: userId
       }
     })
@@ -523,6 +526,7 @@ export class ProjectService {
     )
 
     this.log.debug(`Created project ${newProject}`)
+    console.log(`${Date.now()}: forkProject ${forkMetadata.name} - finished`)
     return newProject
   }
 
@@ -700,6 +704,8 @@ export class ProjectService {
     page: number,
     limit: number
   ) {
+    console.log(`${Date.now()}: getAllProjectForks - started`)
+
     const project =
       await this.authorizationService.authorizeUserAccessToProject({
         user,
@@ -708,22 +714,33 @@ export class ProjectService {
       })
     const projectId = project.id
 
+    console.log(
+      `${Date.now()}: Parent Project WorkspaceId: ${project.workspaceId}`
+    )
+
     const forks = await this.prisma.project.findMany({
       where: {
         forkedFromId: projectId
       }
     })
 
-    const forksAllowed = forks.filter(async (fork) => {
-      const allowed =
-        (await this.authorizationService.authorizeUserAccessToProject({
-          user,
-          entity: { slug: fork.slug },
-          authorities: [Authority.READ_PROJECT]
-        })) != null
-
-      return allowed
-    })
+    const forksAllowed = await Promise.all(
+      forks.map(async (fork) => {
+        console.log(
+          `${Date.now()}: Fork ${fork.name} Project WorkspaceId: ${fork.workspaceId}`
+        )
+        const allowed =
+          (await this.authorizationService.authorizeUserAccessToProject({
+            user,
+            entity: { slug: fork.slug },
+            authorities: [Authority.READ_PROJECT]
+          })) != null
+
+        return { fork, allowed }
+      })
+    ).then((results) =>
+      results.filter((result) => result.allowed).map((result) => result.fork)
+    )
 
     const items = forksAllowed.slice(page * limit, (page + 1) * limit)
 
@@ -737,6 +754,8 @@ export class ProjectService {
       }
     )
 
+    console.log(`${Date.now()}: getAllProjectForks - finished`)
+
     return { items, metadata }
   }
 
diff --git a/apps/api/src/secret/controller/secret.controller.ts b/apps/api/src/secret/controller/secret.controller.ts
index 7f3e757eb..b4e0e12da 100644
--- a/apps/api/src/secret/controller/secret.controller.ts
+++ b/apps/api/src/secret/controller/secret.controller.ts
@@ -110,4 +110,18 @@ export class SecretController {
       order
     )
   }
+
+  @Get('/:projectSlug/:environmentSlug')
+  @RequiredApiKeyAuthorities(Authority.READ_SECRET)
+  async getAllSecretsOfEnvironment(
+    @CurrentUser() user: AuthenticatedUser,
+    @Param('projectSlug') projectSlug: string,
+    @Param('environmentSlug') environmentSlug: string
+  ) {
+    return await this.secretService.getAllSecretsOfProjectAndEnvironment(
+      user,
+      projectSlug,
+      environmentSlug
+    )
+  }
 }
diff --git a/apps/api/src/secret/secret.e2e.spec.ts b/apps/api/src/secret/secret.e2e.spec.ts
index 917c0f25a..00370e32f 100644
--- a/apps/api/src/secret/secret.e2e.spec.ts
+++ b/apps/api/src/secret/secret.e2e.spec.ts
@@ -1160,4 +1160,102 @@ describe('Secret Controller Tests', () => {
       expect(event.title).toBe('Secret rotated')
     })
   })
+
+  describe('Fetch All Secrets By Project And Environment Tests', () => {
+    it('should be able to fetch all secrets by project and environment', async () => {
+      const response = await app.inject({
+        method: 'GET',
+        url: `/secret/${project1.slug}/${environment1.slug}`,
+        headers: {
+          'x-e2e-user-email': user1.email
+        }
+      })
+
+      expect(response.statusCode).toBe(200)
+      expect(response.json().length).toBe(1)
+
+      const secret = response.json()[0]
+      expect(secret.name).toBe('Secret 1')
+      expect(secret.value).toBe('Secret 1 value')
+      expect(secret.isPlaintext).toBe(true)
+    })
+
+    it('should not be able to fetch all secrets by project and environment if project does not exists', async () => {
+      const response = await app.inject({
+        method: 'GET',
+        url: `/secret/non-existing-project-slug/${environment1.slug}`,
+        headers: {
+          'x-e2e-user-email': user1.email
+        }
+      })
+
+      expect(response.statusCode).toBe(404)
+    })
+
+    it('should not be able to fetch all secrets by project and environment if environment does not exists', async () => {
+      const response = await app.inject({
+        method: 'GET',
+        url: `/secret/${project1.slug}/non-existing-environment-slug`,
+        headers: {
+          'x-e2e-user-email': user1.email
+        }
+      })
+
+      expect(response.statusCode).toBe(404)
+    })
+
+    it('should not be able to fetch all secrets by project and environment if the user has no access to the project', async () => {
+      const response = await app.inject({
+        method: 'GET',
+        url: `/secret/${project1.slug}/${environment1.slug}`,
+        headers: {
+          'x-e2e-user-email': user2.email
+        }
+      })
+
+      expect(response.statusCode).toBe(401)
+    })
+
+    it('should not be sending the plaintext secret if project does not store the private key', async () => {
+      // Get the first environment of project 2
+      const environment = await prisma.environment.findFirst({
+        where: {
+          projectId: project2.id
+        }
+      })
+
+      // Create a secret in project 2
+      await secretService.createSecret(
+        user1,
+        {
+          name: 'Secret 20',
+          entries: [
+            {
+              environmentSlug: environment.slug,
+              value: 'Secret 20 value'
+            }
+          ],
+          rotateAfter: '24',
+          note: 'Secret 20 note'
+        },
+        project2.slug
+      )
+
+      const response = await app.inject({
+        method: 'GET',
+        url: `/secret/${project2.slug}/${environment.slug}`,
+        headers: {
+          'x-e2e-user-email': user1.email
+        }
+      })
+
+      expect(response.statusCode).toBe(200)
+      expect(response.json().length).toBe(1)
+
+      const secret = response.json()[0]
+      expect(secret.name).toBe('Secret 20')
+      expect(secret.value).not.toBe('Secret 20 value')
+      expect(secret.isPlaintext).toBe(false)
+    })
+  })
 })
diff --git a/apps/api/src/secret/service/secret.service.ts b/apps/api/src/secret/service/secret.service.ts
index caf87540f..447a68fc1 100644
--- a/apps/api/src/secret/service/secret.service.ts
+++ b/apps/api/src/secret/service/secret.service.ts
@@ -24,7 +24,10 @@ import { AuthorizationService } from '@/auth/service/authorization.service'
 import { RedisClientType } from 'redis'
 import { REDIS_CLIENT } from '@/provider/redis.provider'
 import { CHANGE_NOTIFIER_RSC } from '@/socket/change-notifier.socket'
-import { ChangeNotificationEvent } from 'src/socket/socket.types'
+import {
+  ChangeNotification,
+  ChangeNotificationEvent
+} from '@/socket/socket.types'
 import { paginate } from '@/common/paginate'
 import {
   addHoursToDate,
@@ -770,6 +773,89 @@ export class SecretService {
     return { items, metadata }
   }
 
+  /**
+   * Gets all secrets of a project and environment
+   * @param user the user performing the action
+   * @param projectSlug the slug of the project
+   * @param environmentSlug the slug of the environment
+   * @returns an array of objects with the secret name and value
+   * @throws {NotFoundException} if the project or environment does not exist
+   * @throws {BadRequestException} if the user does not have the required role
+   */
+  async getAllSecretsOfProjectAndEnvironment(
+    user: AuthenticatedUser,
+    projectSlug: Project['slug'],
+    environmentSlug: Environment['slug']
+  ) {
+    // Fetch the project
+    const project =
+      await this.authorizationService.authorizeUserAccessToProject({
+        user,
+        entity: { slug: projectSlug },
+        authorities: [Authority.READ_SECRET]
+      })
+    const projectId = project.id
+
+    // Check access to the environment
+    const environment =
+      await this.authorizationService.authorizeUserAccessToEnvironment({
+        user,
+        entity: { slug: environmentSlug },
+        authorities: [Authority.READ_ENVIRONMENT]
+      })
+    const environmentId = environment.id
+
+    const secrets = await this.prisma.secret.findMany({
+      where: {
+        projectId,
+        versions: {
+          some: {
+            environmentId
+          }
+        }
+      },
+      include: {
+        lastUpdatedBy: {
+          select: {
+            id: true,
+            name: true
+          }
+        },
+        versions: {
+          where: {
+            environmentId
+          },
+          orderBy: {
+            version: 'desc'
+          },
+          take: 1,
+          include: {
+            environment: {
+              select: {
+                id: true,
+                slug: true
+              }
+            }
+          }
+        }
+      }
+    })
+
+    const response: ChangeNotification[] = []
+
+    for (const secret of secrets) {
+      response.push({
+        name: secret.name,
+        value: project.storePrivateKey
+          ? await decrypt(project.privateKey, secret.versions[0].value)
+          : secret.versions[0].value,
+        isPlaintext: project.storePrivateKey
+      })
+    }
+
+    return response
+  }
+
   /**
    * Rotate values of secrets that have reached their rotation time
    * @param currentTime the current time
diff --git a/apps/api/src/variable/controller/variable.controller.ts b/apps/api/src/variable/controller/variable.controller.ts
index 1a15d29d7..fc967cbd4 100644
--- a/apps/api/src/variable/controller/variable.controller.ts
+++ b/apps/api/src/variable/controller/variable.controller.ts
@@ -106,4 +106,18 @@ export class VariableController {
       order
     )
   }
+
+  @Get('/:projectSlug/:environmentSlug')
+  @RequiredApiKeyAuthorities(Authority.READ_VARIABLE)
+  async getAllVariablesOfEnvironment(
+    @CurrentUser() user: AuthenticatedUser,
+    @Param('projectSlug') projectSlug: string,
+    @Param('environmentSlug') environmentSlug: string
+  ) {
+    return await this.variableService.getAllVariablesOfProjectAndEnvironment(
+      user,
+      projectSlug,
+      environmentSlug
+    )
+  }
 }
diff --git a/apps/api/src/variable/service/variable.service.ts b/apps/api/src/variable/service/variable.service.ts
index d54e48e9a..0abdcc557 100644
--- a/apps/api/src/variable/service/variable.service.ts
+++ b/apps/api/src/variable/service/variable.service.ts
@@ -22,7 +22,10 @@ import { RedisClientType } from 'redis'
 import { REDIS_CLIENT } from '@/provider/redis.provider'
 import { CHANGE_NOTIFIER_RSC } from '@/socket/change-notifier.socket'
 import { AuthorizationService } from '@/auth/service/authorization.service'
-import { ChangeNotificationEvent } from 'src/socket/socket.types'
+import {
+  ChangeNotification,
+  ChangeNotificationEvent
+} from '@/socket/socket.types'
 import { paginate } from '@/common/paginate'
 import { getEnvironmentIdToSlugMap } from '@/common/environment'
 import generateEntitySlug from '@/common/slug-generator'
@@ -715,6 +718,83 @@ export class VariableService {
     return { items, metadata }
   }
 
+  /**
+   * Gets all variables of a project and environment.
+   * @param user the user performing the action
+   * @param projectSlug the slug of the project to get the variables from
+   * @param environmentSlug the slug of the environment to get the variables from
+   * @returns an array of objects containing the name, value and whether the value is a plaintext
+   * @throws `NotFoundException` if the project or environment does not exist
+   * @throws `ForbiddenException` if the user does not have the required authority
+   */
+  async getAllVariablesOfProjectAndEnvironment(
+    user: AuthenticatedUser,
+    projectSlug: Project['slug'],
+    environmentSlug: Environment['slug']
+  ) {
+    // Check if the user has the required authorities in the project
+    const { id: projectId } =
+      await this.authorizationService.authorizeUserAccessToProject({
+        user,
+        entity: { slug: projectSlug },
+        authorities: [Authority.READ_VARIABLE]
+      })
+
+    // Check if the user has the required authorities in the environment
+    const { id: environmentId } =
+      await this.authorizationService.authorizeUserAccessToEnvironment({
+        user,
+        entity: { slug: environmentSlug },
+        authorities: [Authority.READ_ENVIRONMENT]
+      })
+
+    const variables = await this.prisma.variable.findMany({
+      where: {
+        projectId,
+        versions: {
+          some: {
+            environmentId
+          }
+        }
+      },
+      include: {
+        lastUpdatedBy: {
+          select: {
+            id: true,
+            name: true
+          }
+        },
+        versions: {
+          where: {
+            environmentId
+          },
+          select: {
+            value: true,
+            environment: {
+              select: {
+                id: true,
+                slug: true
+              }
+            }
+          },
+          orderBy: {
+            version: 'desc'
+          },
+          take: 1
+        }
+      }
+    })
+
+    return variables.map(
+      (variable) =>
+        ({
+          name: variable.name,
+          value: variable.versions[0].value,
+          isPlaintext: true
+        }) as ChangeNotification
+    )
+  }
+
   /**
    * Checks if a variable with a given name already exists in a project.
    * Throws a ConflictException if the variable already exists.
diff --git a/apps/api/src/variable/variable.e2e.spec.ts b/apps/api/src/variable/variable.e2e.spec.ts
index 70872af83..b17e963a9 100644
--- a/apps/api/src/variable/variable.e2e.spec.ts
+++ b/apps/api/src/variable/variable.e2e.spec.ts
@@ -932,4 +932,60 @@ describe('Variable Controller Tests', () => {
       expect(response.statusCode).toBe(401)
     })
   })
+
+  describe('Get All Variables By Project And Environment Tests', () => {
+    it('should be able to fetch all variables by project and environment', async () => {
+      const response = await app.inject({
+        method: 'GET',
+        url: `/variable/${project1.slug}/${environment1.slug}`,
+        headers: {
+          'x-e2e-user-email': user1.email
+        }
+      })
+
+      expect(response.statusCode).toBe(200)
+      expect(response.json().length).toBe(1)
+
+      const variable = response.json()[0]
+      expect(variable.name).toBe('Variable 1')
+      expect(variable.value).toBe('Variable 1 value')
+      expect(variable.isPlaintext).toBe(true)
+    })
+
+    it('should not be able to fetch all variables by project and environment if the user has no access to the project', async () => {
+      const response = await app.inject({
+        method: 'GET',
+        url: `/variable/${project1.slug}/${environment1.slug}`,
+        headers: {
+          'x-e2e-user-email': user2.email
+        }
+      })
+
+      expect(response.statusCode).toBe(401)
+    })
+
+    it('should not be able to fetch all variables by project and environment if the project does not exist', async () => {
+      const response = await app.inject({
+        method: 'GET',
+        url: `/variable/non-existing-project-slug/${environment1.slug}`,
+        headers: {
+          'x-e2e-user-email': user1.email
+        }
+      })
+
+      expect(response.statusCode).toBe(404)
+    })
+
+    it('should not be able to fetch all variables by project and environment if the environment does not exist', async () => {
+      const response = await app.inject({
+        method: 'GET',
+        url: `/variable/${project1.slug}/non-existing-environment-slug`,
+        headers: {
+          'x-e2e-user-email': user1.email
+        }
+      })
+
+      expect(response.statusCode).toBe(404)
+    })
+  })
 })
diff --git a/apps/cli/src/commands/run.command.ts b/apps/cli/src/commands/run.command.ts
index 43bdfec63..5b624543d 100644
--- a/apps/cli/src/commands/run.command.ts
+++ b/apps/cli/src/commands/run.command.ts
@@ -160,9 +160,10 @@ export default class RunCommand extends BaseCommand {
       }
       if (childProcess === null) {
         childProcess = spawn(command, {
+          // @ts-expect-error this just works
           stdio: ['inherit', 'pipe', 'pipe'],
           shell: true,
-          env: this.processEnvironmentalVariables,
+          env: { ...process.env, ...this.processEnvironmentalVariables },
           detached: true
         })
 
diff --git a/packages/api-client/src/controllers/secret.ts b/packages/api-client/src/controllers/secret.ts
index a4d961d9c..176f1cd70 100644
--- a/packages/api-client/src/controllers/secret.ts
+++ b/packages/api-client/src/controllers/secret.ts
@@ -1,5 +1,9 @@
 import { APIClient } from '@api-client/core/client'
-import { ClientResponse } from '@keyshade/schema'
+import {
+  ClientResponse,
+  GetAllSecretsOfEnvironmentRequest,
+  GetAllSecretsOfEnvironmentResponse
+} from '@keyshade/schema'
 import { parseResponse } from '@api-client/core/response-parser'
 import {
   CreateSecretRequest,
@@ -106,4 +110,14 @@ export default class SecretController {
 
     return await parseResponse<GetRevisionsOfSecretResponse>(response)
   }
+
+  async getAllSecretsOfEnvironment(
+    request: GetAllSecretsOfEnvironmentRequest,
+    headers?: Record<string, string>
+  ): Promise<ClientResponse<GetAllSecretsOfEnvironmentResponse>> {
+    const url = `/api/secret/${request.projectSlug}/${request.environmentSlug}`
+    const response = await this.apiClient.get(url, headers)
+
+    return await parseResponse<GetAllSecretsOfEnvironmentResponse>(response)
+  }
 }
diff --git a/packages/api-client/src/controllers/variable.ts b/packages/api-client/src/controllers/variable.ts
index de60d6eaa..d6ed0b23d 100644
--- a/packages/api-client/src/controllers/variable.ts
+++ b/packages/api-client/src/controllers/variable.ts
@@ -1,7 +1,11 @@
 import { APIClient } from '@api-client/core/client'
 import { parsePaginationUrl } from '@api-client/core/pagination-parser'
 import { parseResponse } from '@api-client/core/response-parser'
-import { ClientResponse } from '@keyshade/schema'
+import {
+  ClientResponse,
+  GetAllVariablesOfEnvironmentRequest,
+  GetAllVariablesOfEnvironmentResponse
+} from '@keyshade/schema'
 import {
   CreateVariableRequest,
   CreateVariableResponse,
@@ -99,4 +103,14 @@ export default class VariableController {
 
     return await parseResponse<GetRevisionsOfVariableResponse>(response)
   }
+
+  async getAllVariablesOfEnvironment(
+    request: GetAllVariablesOfEnvironmentRequest,
+    headers: Record<string, string>
+  ): Promise<ClientResponse<GetAllVariablesOfEnvironmentResponse>> {
+    const url = `/api/variable/${request.projectSlug}/${request.environmentSlug}`
+    const response = await this.apiClient.get(url, headers)
+
+    return await parseResponse<GetAllVariablesOfEnvironmentResponse>(response)
+  }
 }
diff --git a/packages/schema/src/secret/index.ts b/packages/schema/src/secret/index.ts
index e075354ba..0b1879d38 100644
--- a/packages/schema/src/secret/index.ts
+++ b/packages/schema/src/secret/index.ts
@@ -129,3 +129,16 @@ export const GetRevisionsOfSecretResponseSchema = PageResponseSchema(
     })
   })
 )
+
+export const GetAllSecretsOfEnvironmentRequestSchema = z.object({
+  projectSlug: BaseProjectSchema.shape.slug,
+  environmentSlug: EnvironmentSchema.shape.slug
+})
+
+export const GetAllSecretsOfEnvironmentResponseSchema = z.array(
+  z.object({
+    name: z.string(),
+    value: z.string(),
+    isPlaintext: z.boolean()
+  })
+)
diff --git a/packages/schema/src/secret/index.types.ts b/packages/schema/src/secret/index.types.ts
index 43920ad29..990bf9cf7 100644
--- a/packages/schema/src/secret/index.types.ts
+++ b/packages/schema/src/secret/index.types.ts
@@ -12,7 +12,9 @@ import {
   GetAllSecretsOfProjectRequestSchema,
   GetAllSecretsOfProjectResponseSchema,
   GetRevisionsOfSecretRequestSchema,
-  GetRevisionsOfSecretResponseSchema
+  GetRevisionsOfSecretResponseSchema,
+  GetAllSecretsOfEnvironmentRequestSchema,
+  GetAllSecretsOfEnvironmentResponseSchema
 } from '.'
 
 export type Secret = z.infer<typeof SecretSchema>
@@ -50,3 +52,11 @@ export type GetRevisionsOfSecretRequest = z.infer<
 export type GetRevisionsOfSecretResponse = z.infer<
   typeof GetRevisionsOfSecretResponseSchema
 >
+
+export type GetAllSecretsOfEnvironmentRequest = z.infer<
+  typeof GetAllSecretsOfEnvironmentRequestSchema
+>
+
+export type GetAllSecretsOfEnvironmentResponse = z.infer<
+  typeof GetAllSecretsOfEnvironmentResponseSchema
+>
diff --git a/packages/schema/src/variable/index.ts b/packages/schema/src/variable/index.ts
index 810e5ba2a..d127db4bc 100644
--- a/packages/schema/src/variable/index.ts
+++ b/packages/schema/src/variable/index.ts
@@ -133,3 +133,16 @@ export const GetRevisionsOfVariableResponseSchema = PageResponseSchema(
     })
   })
 )
+
+export const GetAllVariablesOfEnvironmentRequestSchema = z.object({
+  projectSlug: BaseProjectSchema.shape.slug,
+  environmentSlug: EnvironmentSchema.shape.slug
+})
+
+export const GetAllVariablesOfEnvironmentResponseSchema = z.array(
+  z.object({
+    name: z.string(),
+    value: z.string(),
+    isPlaintext: z.boolean()
+  })
+)
diff --git a/packages/schema/src/variable/index.types.ts b/packages/schema/src/variable/index.types.ts
index 609fbb24f..6bf88352b 100644
--- a/packages/schema/src/variable/index.types.ts
+++ b/packages/schema/src/variable/index.types.ts
@@ -12,7 +12,9 @@ import {
   GetAllVariablesOfProjectRequestSchema,
   GetAllVariablesOfProjectResponseSchema,
   GetRevisionsOfVariableRequestSchema,
-  GetRevisionsOfVariableResponseSchema
+  GetRevisionsOfVariableResponseSchema,
+  GetAllVariablesOfEnvironmentRequestSchema,
+  GetAllVariablesOfEnvironmentResponseSchema
 } from '.'
 
 export type Variable = z.infer<typeof VariableSchema>
@@ -58,3 +60,11 @@ export type GetRevisionsOfVariableRequest = z.infer<
 export type GetRevisionsOfVariableResponse = z.infer<
   typeof GetRevisionsOfVariableResponseSchema
 >
+
+export type GetAllVariablesOfEnvironmentRequest = z.infer<
+  typeof GetAllVariablesOfEnvironmentRequestSchema
+>
+
+export type GetAllVariablesOfEnvironmentResponse = z.infer<
+  typeof GetAllVariablesOfEnvironmentResponseSchema
+>