diff --git a/.env.example b/.env.example
index c57a09b2c2..3dd78566a2 100644
--- a/.env.example
+++ b/.env.example
@@ -40,6 +40,9 @@ DATABASE_URL='mysql://root:@localhost:3306/planetscale'
 # Generate a value by running `openssl rand -hex 32`
 DATABASE_ENCRYPTION_KEY=
 
+# Video privacy settings
+# Set to false to make new uploaded videos private by default. If not set or set to true, videos are public by default.
+# CAP_VIDEOS_DEFAULT_PUBLIC=true
 
 ## AWS/S3
 
diff --git a/apps/web/actions/caps/share.ts b/apps/web/actions/caps/share.ts
index 86853cb558..762f0c1a15 100644
--- a/apps/web/actions/caps/share.ts
+++ b/apps/web/actions/caps/share.ts
@@ -4,17 +4,17 @@ import { revalidatePath } from 'next/cache'
 import { db } from "@cap/database"
 import { getCurrentUser } from "@cap/database/auth/session"
 import { sharedVideos, videos, spaces, organizationMembers, organizations, spaceVideos } from "@cap/database/schema"
-import { eq, and, inArray, or } from "drizzle-orm"
+import { eq, and, inArray } from "drizzle-orm"
 import { nanoId } from "@cap/database/helpers"
 
 interface ShareCapParams {
   capId: string
   spaceIds: string[]
+  public?: boolean
 }
 
-export async function shareCap({ capId, spaceIds }: ShareCapParams) {
+export async function shareCap({ capId, spaceIds, public: isPublic }: ShareCapParams) {
   try {
-    
     const user = await getCurrentUser()
     if (!user) {
       return { success: false, error: "Unauthorized" }
@@ -122,6 +122,15 @@ export async function shareCap({ capId, spaceIds }: ShareCapParams) {
         })
       }
     }
+
+    // Update public status if provided
+    if (typeof isPublic === 'boolean') {
+      await db()
+        .update(videos)
+        .set({ public: isPublic })
+        .where(eq(videos.id, capId))
+    }
+
     revalidatePath('/dashboard/caps')
     revalidatePath(`/dashboard/caps/${capId}`)
     return { success: true }
diff --git a/apps/web/actions/video/upload.ts b/apps/web/actions/video/upload.ts
index c572be02ba..82aabdd46b 100644
--- a/apps/web/actions/video/upload.ts
+++ b/apps/web/actions/video/upload.ts
@@ -224,6 +224,7 @@ export async function createVideoAndGetUploadUrl({
       source: { type: "desktopMP4" as const },
       isScreenshot,
       bucket: customBucket?.id,
+      public: serverEnv().CAP_VIDEOS_DEFAULT_PUBLIC,
       ...(folderId ? { folderId } : {}),
     };
 
diff --git a/apps/web/app/(org)/dashboard/caps/Caps.tsx b/apps/web/app/(org)/dashboard/caps/Caps.tsx
index 317c5731fd..ccd338a311 100644
--- a/apps/web/app/(org)/dashboard/caps/Caps.tsx
+++ b/apps/web/app/(org)/dashboard/caps/Caps.tsx
@@ -26,6 +26,7 @@ export type VideoData = {
   ownerId: string;
   name: string;
   createdAt: Date;
+  public: boolean;
   totalComments: number;
   totalReactions: number;
   foldersData: FolderDataType[];
diff --git a/apps/web/app/(org)/dashboard/caps/components/CapCard/CapCard.tsx b/apps/web/app/(org)/dashboard/caps/components/CapCard/CapCard.tsx
index e8185cdab8..d7a146ed39 100644
--- a/apps/web/app/(org)/dashboard/caps/components/CapCard/CapCard.tsx
+++ b/apps/web/app/(org)/dashboard/caps/components/CapCard/CapCard.tsx
@@ -34,6 +34,7 @@ export interface CapCardProps extends PropsWithChildren {
     ownerId: string;
     name: string;
     createdAt: Date;
+    public?: boolean;
     totalComments: number;
     totalReactions: number;
     sharedOrganizations?: {
@@ -256,6 +257,7 @@ export const CapCard = ({
         capName={cap.name}
         sharedSpaces={cap.sharedSpaces || []}
         onSharingUpdated={handleSharingUpdated}
+        isPublic={cap.public}
       />
       <PasswordDialog
         isOpen={isPasswordDialogOpen}
diff --git a/apps/web/app/(org)/dashboard/caps/components/CapCard/CapCardContent.tsx b/apps/web/app/(org)/dashboard/caps/components/CapCard/CapCardContent.tsx
index 71a556eb44..b46bca5b39 100644
--- a/apps/web/app/(org)/dashboard/caps/components/CapCard/CapCardContent.tsx
+++ b/apps/web/app/(org)/dashboard/caps/components/CapCard/CapCardContent.tsx
@@ -144,10 +144,10 @@ export const CapCardContent: React.FC<CapContentProps> = ({
       hideSharedStatus ? "pointer-events-none" : "cursor-pointer"
     );
     if (isOwner && !hideSharedStatus) {
-      if (
-        (cap.sharedOrganizations?.length === 0 || !cap.sharedOrganizations) &&
-        (cap.sharedSpaces?.length === 0 || !cap.sharedSpaces)
-      ) {
+      const hasSpaceSharing = (cap.sharedOrganizations?.length ?? 0) > 0 || (cap.sharedSpaces?.length ?? 0) > 0;
+      const isPublic = cap.public;
+
+      if (!hasSpaceSharing && !isPublic) {
         return (
           <p
             className={baseClassName}
diff --git a/apps/web/app/(org)/dashboard/caps/components/SharingDialog.tsx b/apps/web/app/(org)/dashboard/caps/components/SharingDialog.tsx
index 665c554877..c1af2c51e9 100644
--- a/apps/web/app/(org)/dashboard/caps/components/SharingDialog.tsx
+++ b/apps/web/app/(org)/dashboard/caps/components/SharingDialog.tsx
@@ -8,17 +8,19 @@ import {
   DialogTitle,
   Input,
   Avatar,
+  Switch,
 } from "@cap/ui";
 import { faShareNodes, faCopy } from "@fortawesome/free-solid-svg-icons";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import clsx from "clsx";
 import { motion } from "framer-motion";
-import { Check, Search } from "lucide-react";
+import { Check, Search, Globe2 } from "lucide-react";
 import Image from "next/image";
 import { useCallback, useEffect, useState } from "react";
 import { toast } from "sonner";
 import { shareCap } from "@/actions/caps/share";
 import { useDashboardContext } from "@/app/(org)/dashboard/Contexts";
+import { Spaces } from "@/app/(org)/dashboard/dashboard-data";
 
 interface SharingDialogProps {
   isOpen: boolean;
@@ -32,6 +34,8 @@ interface SharingDialogProps {
     organizationId: string;
   }[];
   onSharingUpdated: (updatedSharedSpaces: string[]) => void;
+  isPublic?: boolean;
+  spacesData?: Spaces[] | null;
 }
 
 export const SharingDialog: React.FC<SharingDialogProps> = ({
@@ -41,17 +45,22 @@ export const SharingDialog: React.FC<SharingDialogProps> = ({
   capName,
   sharedSpaces,
   onSharingUpdated,
+  isPublic = false,
+  spacesData: propSpacesData = null,
 }) => {
-  const { spacesData } = useDashboardContext();
+  const { spacesData: contextSpacesData } = useDashboardContext();
+  const spacesData = propSpacesData || contextSpacesData;
   const [selectedSpaces, setSelectedSpaces] = useState<Set<string>>(new Set());
   const [searchTerm, setSearchTerm] = useState("");
   const [initialSelectedSpaces, setInitialSelectedSpaces] = useState<
     Set<string>
   >(new Set());
   const [loading, setLoading] = useState(false);
-  const tabs = ["Share to space", "Embed"] as const;
+  const [publicToggle, setPublicToggle] = useState(isPublic);
+  const [initialPublicState, setInitialPublicState] = useState(isPublic);
+  const tabs = ["Share", "Embed"] as const;
   const [activeTab, setActiveTab] =
-    useState<(typeof tabs)[number]>("Share to space");
+    useState<(typeof tabs)[number]>("Share");
 
   const sharedSpaceIds = new Set(sharedSpaces?.map((space) => space.id) || []);
 
@@ -60,10 +69,12 @@ export const SharingDialog: React.FC<SharingDialogProps> = ({
       const spaceIds = new Set(sharedSpaces.map((space) => space.id));
       setSelectedSpaces(spaceIds);
       setInitialSelectedSpaces(spaceIds);
+      setPublicToggle(isPublic);
+      setInitialPublicState(isPublic);
       setSearchTerm("");
       setActiveTab(tabs[0]);
     }
-  }, [isOpen, sharedSpaces]);
+  }, [isOpen, sharedSpaces, isPublic]);
 
   const isSpaceSharedViaOrganization = useCallback(
     (spaceId: string) => {
@@ -92,6 +103,7 @@ export const SharingDialog: React.FC<SharingDialogProps> = ({
       const result = await shareCap({
         capId,
         spaceIds: Array.from(selectedSpaces),
+        public: publicToggle,
       });
 
       if (!result.success) {
@@ -108,22 +120,26 @@ export const SharingDialog: React.FC<SharingDialogProps> = ({
         (id) => !newSelectedSpaces.includes(id)
       );
 
+      const publicChanged = publicToggle !== initialPublicState;
+
       const getSpaceName = (id: string) => {
         const space = spacesData?.find((space) => space.id === id);
         return space?.name || `Space ${id}`;
       };
 
-      if (addedSpaceIds.length === 1 && removedSpaceIds.length === 0) {
+      if (publicChanged && addedSpaceIds.length === 0 && removedSpaceIds.length === 0) {
+        toast.success(publicToggle ? "Video is now public" : "Video is now private");
+      } else if (addedSpaceIds.length === 1 && removedSpaceIds.length === 0 && !publicChanged) {
         toast.success(`Shared to ${getSpaceName(addedSpaceIds[0] as string)}`);
-      } else if (removedSpaceIds.length === 1 && addedSpaceIds.length === 0) {
+      } else if (removedSpaceIds.length === 1 && addedSpaceIds.length === 0 && !publicChanged) {
         toast.success(
           `Unshared from ${getSpaceName(removedSpaceIds[0] as string)}`
         );
-      } else if (addedSpaceIds.length > 0 && removedSpaceIds.length === 0) {
+      } else if (addedSpaceIds.length > 0 && removedSpaceIds.length === 0 && !publicChanged) {
         toast.success(`Shared to ${addedSpaceIds.length} spaces`);
-      } else if (removedSpaceIds.length > 0 && addedSpaceIds.length === 0) {
+      } else if (removedSpaceIds.length > 0 && addedSpaceIds.length === 0 && !publicChanged) {
         toast.success(`Unshared from ${removedSpaceIds.length} spaces`);
-      } else if (addedSpaceIds.length > 0 && removedSpaceIds.length > 0) {
+      } else if (addedSpaceIds.length > 0 || removedSpaceIds.length > 0 || publicChanged) {
         toast.success(`Sharing settings updated`);
       } else {
         toast.info("No changes to sharing settings");
@@ -139,7 +155,7 @@ export const SharingDialog: React.FC<SharingDialogProps> = ({
 
   const handleCopyEmbedCode = async () => {
     const embedCode = `<div style="position: relative; padding-bottom: 56.25%; height: 0;"><iframe src="${process.env.NODE_ENV === "development"
-      ? "http://localhost:3000"
+      ? process.env.NEXT_PUBLIC_WEB_URL
       : "https://cap.so"
       }/embed/${capId}" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"></iframe></div>`;
 
@@ -151,11 +167,24 @@ export const SharingDialog: React.FC<SharingDialogProps> = ({
     }
   };
 
+  // Separate organization entries from real spaces
+  const organizationEntries = spacesData?.filter((space) =>
+    space.id === space.organizationId && space.primary === true
+  ) || [];
+
+  const realSpaces = spacesData?.filter((space) =>
+    !(space.id === space.organizationId && space.primary === true)
+  ) || [];
+
+  const allShareableItems = [...organizationEntries, ...realSpaces];
+
   const filteredSpaces = searchTerm
-    ? spacesData?.filter((space) =>
+    ? allShareableItems.filter((space) =>
       space.name.toLowerCase().includes(searchTerm.toLowerCase())
     )
-    : spacesData;
+    : allShareableItems;
+
+
 
   return (
     <Dialog open={isOpen} onOpenChange={onClose}>
@@ -163,13 +192,13 @@ export const SharingDialog: React.FC<SharingDialogProps> = ({
         <DialogHeader
           icon={<FontAwesomeIcon icon={faShareNodes} className="size-3.5" />}
           description={
-            activeTab === "Share to space"
-              ? "Select the spaces you would like to share with"
+            activeTab === "Share"
+              ? "Select how you would like to share the cap"
               : "Copy the embed code to share your cap"
           }
         >
           <DialogTitle className="truncate w-full max-w-[320px]">
-            {activeTab === "Share to space"
+            {activeTab === "Share"
               ? `Share ${capName}`
               : `Embed ${capName}`}
           </DialogTitle>
@@ -202,12 +231,29 @@ export const SharingDialog: React.FC<SharingDialogProps> = ({
         </div>
 
         <div className="p-5">
-          {activeTab === "Share to space" ? (
+          {activeTab === "Share" ? (
             <>
+              {/* Public sharing toggle */}
+              <div className="flex items-center justify-between p-3 mb-4 rounded-lg border bg-gray-1 border-gray-4">
+                <div className="flex items-center gap-3">
+                  <div className="flex items-center justify-center w-8 h-8 rounded-full bg-gray-3">
+                    <Globe2 className="w-4 h-4 text-gray-11" />
+                  </div>
+                  <div>
+                    <p className="text-sm font-medium text-gray-12">Anyone with the link</p>
+                    <p className="text-xs text-gray-10">{publicToggle ? 'Anyone on the internet with the link can view': 'Only people with access can view'}</p>
+                  </div>
+                </div>
+                <Switch
+                  checked={publicToggle}
+                  onCheckedChange={setPublicToggle}
+                />
+              </div>
+
               <div className="relative mb-3">
                 <Input
                   type="text"
-                  placeholder="Search..."
+                  placeholder="Search and add to spaces..."
                   value={searchTerm}
                   className="pr-8"
                   onChange={(e) => setSearchTerm(e.target.value)}
@@ -233,7 +279,7 @@ export const SharingDialog: React.FC<SharingDialogProps> = ({
                 ) : (
                   <div className="flex col-span-5 gap-2 justify-center items-center text-sm">
                     <p className="text-gray-12">
-                      {spacesData && spacesData.length > 0
+                      {allShareableItems && allShareableItems.length > 0
                         ? "No spaces match your search"
                         : "No spaces available"}
                     </p>
@@ -246,7 +292,7 @@ export const SharingDialog: React.FC<SharingDialogProps> = ({
               <div className="p-3 rounded-lg border bg-gray-3 border-gray-4">
                 <code className="font-mono text-xs break-all text-gray-11">
                   {`<div style="position: relative; padding-bottom: 56.25%; height: 0;"><iframe src="${process.env.NODE_ENV === "development"
-                    ? "http://localhost:3000"
+                    ? process.env.NEXT_PUBLIC_WEB_URL
                     : "https://cap.so"
                     }/embed/${capId}" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"></iframe></div>`}
                 </code>
@@ -264,7 +310,7 @@ export const SharingDialog: React.FC<SharingDialogProps> = ({
         </div>
 
         <DialogFooter className="p-5 border-t border-gray-4">
-          {activeTab === "Share to space" ? (
+          {activeTab === "Share" ? (
             <>
               <Button size="sm" variant="gray" onClick={onClose}>
                 Cancel
diff --git a/apps/web/app/(org)/dashboard/caps/page.tsx b/apps/web/app/(org)/dashboard/caps/page.tsx
index 40d658294c..4c15eef8fc 100644
--- a/apps/web/app/(org)/dashboard/caps/page.tsx
+++ b/apps/web/app/(org)/dashboard/caps/page.tsx
@@ -145,6 +145,7 @@ export default async function CapsPage({
       name: videos.name,
       createdAt: videos.createdAt,
       metadata: videos.metadata,
+      public: videos.public,
       totalComments: sql<number>`COUNT(DISTINCT CASE WHEN ${comments.type} = 'text' THEN ${comments.id} END)`,
       totalReactions: sql<number>`COUNT(DISTINCT CASE WHEN ${comments.type} = 'emoji' THEN ${comments.id} END)`,
       sharedOrganizations: sql<{ id: string; name: string; iconUrl: string }[]>`
diff --git a/apps/web/app/api/desktop/[...route]/video.ts b/apps/web/app/api/desktop/[...route]/video.ts
index 6b97863af3..b7d9e14534 100644
--- a/apps/web/app/api/desktop/[...route]/video.ts
+++ b/apps/web/app/api/desktop/[...route]/video.ts
@@ -102,6 +102,7 @@ app.get(
               : undefined,
           isScreenshot,
           bucket: customBucket?.id,
+          public: serverEnv().CAP_VIDEOS_DEFAULT_PUBLIC,
           metadata: {
             duration,
           },
diff --git a/apps/web/app/embed/[videoId]/page.tsx b/apps/web/app/embed/[videoId]/page.tsx
index c5671f94c7..358810d913 100644
--- a/apps/web/app/embed/[videoId]/page.tsx
+++ b/apps/web/app/embed/[videoId]/page.tsx
@@ -11,6 +11,7 @@ import { VideoMetadata } from "@cap/database/types";
 import { getCurrentUser } from "@cap/database/auth/session";
 import type { Metadata } from "next";
 import { notFound } from "next/navigation";
+import Link from "next/link";
 import { buildEnv } from "@cap/env";
 import { transcribeVideo } from "@/actions/videos/transcribe";
 import { isAiGenerationEnabled } from "@/utils/flags";
@@ -41,7 +42,10 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
     return notFound();
   }
 
-  if (video.public === false) {
+  const userPromise = getCurrentUser();
+  const userAccess = await userHasAccessToVideo(userPromise, video);
+
+  if (video.public === false && userAccess !== "has-access") {
     return {
       title: "Cap: This video is private",
       description: "This video is private and cannot be shared.",
@@ -49,7 +53,7 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
     };
   }
 
-  if (video.password !== null) {
+  if (video.password !== null && userAccess !== "has-access") {
     return {
       title: "Cap: Password Protected Video",
       description: "This video is password protected.",
@@ -159,8 +163,11 @@ export default async function EmbedVideoPage(props: Props) {
 
   if (userAccess === "private") {
     return (
-      <div className="min-h-screen flex items-center justify-center bg-black text-white">
-        <p>This video is private</p>
+      <div className="flex flex-col justify-center items-center min-h-screen text-center bg-black text-white">
+        <h1 className="mb-4 text-2xl font-bold">This video is private</h1>
+        <p className="text-gray-400">
+          If you own this video, please <Link href="/login">sign in</Link> to manage sharing.
+        </p>
       </div>
     );
   }
diff --git a/apps/web/app/s/[videoId]/_components/ShareHeader.tsx b/apps/web/app/s/[videoId]/_components/ShareHeader.tsx
index 3b51e40546..6900f6b7da 100644
--- a/apps/web/app/s/[videoId]/_components/ShareHeader.tsx
+++ b/apps/web/app/s/[videoId]/_components/ShareHeader.tsx
@@ -18,6 +18,7 @@ import { UpgradeModal } from "@/components/UpgradeModal";
 import clsx from "clsx";
 import { useDashboardContext } from "@/app/(org)/dashboard/Contexts";
 import { SharingDialog } from "@/app/(org)/dashboard/caps/components/SharingDialog";
+import { Spaces } from "@/app/(org)/dashboard/dashboard-data";
 
 export const ShareHeader = ({
   data,
@@ -26,6 +27,7 @@ export const ShareHeader = ({
   domainVerified,
   sharedOrganizations = [],
   sharedSpaces = [],
+  spacesData = null,
   NODE_ENV,
 }: {
   data: typeof videos.$inferSelect;
@@ -46,6 +48,7 @@ export const ShareHeader = ({
     iconUrl?: string;
     organizationId: string;
   }[];
+  spacesData?: Spaces[] | null;
   NODE_ENV: "production" | "development" | "test";
 }) => {
   const { push, refresh } = useRouter();
@@ -135,10 +138,10 @@ export const ShareHeader = ({
       "text-sm text-gray-10 transition-colors duration-200 flex items-center";
 
     if (isOwner) {
-      if (
-        (sharedOrganizations?.length === 0 || !sharedOrganizations) &&
-        (effectiveSharedSpaces?.length === 0 || !effectiveSharedSpaces)
-      ) {
+      const hasSpaceSharing = (sharedOrganizations?.length > 0) || (effectiveSharedSpaces?.length > 0);
+      const isPublic = data.public;
+
+      if (!hasSpaceSharing && !isPublic) {
         return (
           <p
             className={clsx(baseClassName, "cursor-pointer hover:text-gray-12")}
@@ -173,6 +176,8 @@ export const ShareHeader = ({
         capName={data.name}
         sharedSpaces={effectiveSharedSpaces || []}
         onSharingUpdated={handleSharingUpdated}
+        isPublic={data.public}
+        spacesData={spacesData}
       />
       <div>
         <div className="space-x-0 md:flex md:items-center md:justify-between md:space-x-6">
diff --git a/apps/web/app/s/[videoId]/page.tsx b/apps/web/app/s/[videoId]/page.tsx
index f9f7f860a3..66251186c2 100644
--- a/apps/web/app/s/[videoId]/page.tsx
+++ b/apps/web/app/s/[videoId]/page.tsx
@@ -9,11 +9,14 @@ import {
   sharedVideos,
   organizationMembers,
   organizations,
+  spaces,
+  spaceVideos,
 } from "@cap/database/schema";
 import { VideoMetadata } from "@cap/database/types";
 import { getCurrentUser } from "@cap/database/auth/session";
 import type { Metadata } from "next";
 import { notFound } from "next/navigation";
+import Link from "next/link";
 import { buildEnv } from "@cap/env";
 import { getVideoAnalytics } from "@/actions/videos/get-analytics";
 import { transcribeVideo } from "@/actions/videos/transcribe";
@@ -25,11 +28,69 @@ import { Share } from "./Share";
 import { PasswordOverlay } from "./_components/PasswordOverlay";
 import { ShareHeader } from "./_components/ShareHeader";
 import { userHasAccessToVideo } from "@/utils/auth";
+import { getDashboardData } from "@/app/(org)/dashboard/dashboard-data";
 
 export const dynamic = "auto";
 export const dynamicParams = true;
 export const revalidate = 30;
 
+// Helper function to fetch shared spaces data for a video
+async function getSharedSpacesForVideo(videoId: string) {
+  // Fetch space-level sharing
+  const spaceSharing = await db()
+    .select({
+      id: spaces.id,
+      name: spaces.name,
+      organizationId: spaces.organizationId,
+      iconUrl: organizations.iconUrl,
+    })
+    .from(spaceVideos)
+    .innerJoin(spaces, eq(spaceVideos.spaceId, spaces.id))
+    .innerJoin(organizations, eq(spaces.organizationId, organizations.id))
+    .where(eq(spaceVideos.videoId, videoId));
+
+  // Fetch organization-level sharing
+  const orgSharing = await db()
+    .select({
+      id: organizations.id,
+      name: organizations.name,
+      organizationId: organizations.id,
+      iconUrl: organizations.iconUrl,
+    })
+    .from(sharedVideos)
+    .innerJoin(organizations, eq(sharedVideos.organizationId, organizations.id))
+    .where(eq(sharedVideos.videoId, videoId));
+
+  const sharedSpaces: Array<{
+    id: string;
+    name: string;
+    organizationId: string;
+    iconUrl?: string;
+  }> = [];
+
+  // Add space-level sharing
+  spaceSharing.forEach(space => {
+    sharedSpaces.push({
+      id: space.id,
+      name: space.name,
+      organizationId: space.organizationId,
+      iconUrl: space.iconUrl || undefined,
+    });
+  });
+
+  // Add organization-level sharing
+  orgSharing.forEach(org => {
+    sharedSpaces.push({
+      id: org.id,
+      name: org.name,
+      organizationId: org.organizationId,
+      iconUrl: org.iconUrl || undefined,
+    });
+  });
+
+  return sharedSpaces;
+}
+
 type Props = {
   params: { [key: string]: string | string[] | undefined };
 };
@@ -68,6 +129,9 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
     return notFound();
   }
 
+  const userPromise = getCurrentUser();
+  const userAccess = await userHasAccessToVideo(userPromise, video);
+
   const headersList = headers();
   const referrer = headersList.get("x-referrer") || "";
 
@@ -89,7 +153,7 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
     ? "index, follow"
     : "noindex, nofollow";
 
-  if (video.public === false) {
+  if (video.public === false && userAccess !== "has-access") {
     return {
       title: "Cap: This video is private",
       description: "This video is private and cannot be shared.",
@@ -120,7 +184,7 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
     };
   }
 
-  if (video.password !== null) {
+  if (video.password !== null && userAccess !== "has-access") {
     return {
       title: "Cap: Password Protected Video",
       description: "This video is password protected.",
@@ -248,7 +312,16 @@ export default async function ShareVideoPage(props: Props) {
 
   const userAccess = await userHasAccessToVideo(userPromise, video);
 
-  if (userAccess === "private") return <p>This video is private</p>;
+  if (userAccess === "private") {
+    return (
+      <div className="flex flex-col justify-center items-center p-4 min-h-screen text-center">
+        <h1 className="mb-4 text-2xl font-bold">This video is private</h1>
+        <p className="text-gray-400">
+          If you own this video, please <Link href="/login">sign in</Link> to manage sharing.
+        </p>
+      </div>
+    );
+  }
 
   return (
     <div className="min-h-screen flex flex-col bg-[#F7F8FA]">
@@ -276,6 +349,21 @@ async function AuthorizedContent({
   const videoId = video.id;
   const userId = user?.id;
 
+  // Fetch spaces data for the sharing dialog
+  let spacesData = null;
+  if (user) {
+    try {
+      const dashboardData = await getDashboardData(user);
+      spacesData = dashboardData.spacesData;
+    } catch (error) {
+      console.error("Failed to fetch spaces data for sharing dialog:", error);
+      spacesData = [];
+    }
+  }
+
+  // Fetch shared spaces data for this video
+  const sharedSpaces = await getSharedSpacesForVideo(videoId);
+
   let aiGenerationEnabled = false;
   const videoOwnerQuery = await db()
     .select({
@@ -547,7 +635,9 @@ async function AuthorizedContent({
           sharedOrganizations={
             videoWithOrganizationInfo.sharedOrganizations || []
           }
+          sharedSpaces={sharedSpaces}
           userOrganizations={userOrganizations}
+          spacesData={spacesData}
           NODE_ENV={process.env.NODE_ENV}
         />
 
diff --git a/packages/env/server.ts b/packages/env/server.ts
index dd9f7dd0ef..0370f3ada1 100644
--- a/packages/env/server.ts
+++ b/packages/env/server.ts
@@ -44,6 +44,7 @@ function createServerEnv() {
       OPENAI_API_KEY: z.string().optional(),
       GROQ_API_KEY: z.string().optional(),
       INTERCOM_SECRET: z.string().optional(),
+      CAP_VIDEOS_DEFAULT_PUBLIC: boolString(true),
       VERCEL_ENV: z
         .union([
           z.literal("production"),
