# Global Guard (https://v1.s3.dimah.dev/docs/server/hooks/global-guard)

Define `guard` on `dimahS3()` to run it for every incoming request before
route resolution or plugin execution.

Use it for system-wide checks like user authentication, IP filtering, or tenant context.

A signed-in session here does not prove the caller owns a particular object
key — that belongs on `download.guard` / `delete.guard` or [`db()`](https://v1.s3.dimah.dev/docs/db). See
[Security](https://v1.s3.dimah.dev/docs/server/security#route-namespace-vs-ownership).

```ts title="lib/s3.ts"
import { S3Client } from "@aws-sdk/client-s3";
import { dimahS3, errors, route } from "@dimah-s3/server";

export const awsS3 = new S3Client({/* env */});

export const s3 = dimahS3({
  client: awsS3,
  bucket: process.env.S3_BUCKET!,
  guard: async ({ request }) => {
    // [!code ++]
    const session = await getSession(request); // [!code ++]
    if (!session) throw errors.unauthorized(); // [!code ++]
  }, // [!code ++]
  routes: {
    avatar: route({
      upload: {
        fileTypes: ["image/*"],
        maxFileSize: 2 * 1024 * 1024,
      },
    }),
  },
});
```

---

## Guard context [#guard-context]

The global guard receives the raw `request` object. Route name and target key are resolved later in the lifecycle.

```ts
import type { GuardContext } from "@dimah-s3/server";
```

<AutoTypeTable
  path="packages/server/src/types/hook-contexts.ts"
  name="GuardContext"
/>

## Frequently asked questions [#frequently-asked-questions]

<Accordions>

<Accordion title="When should I use route.guard instead of global guard?">

Use `route.guard` when only some routes need the policy. For example, an app
with public media uploads and private invoices can leave the global `guard`
unset and protect specific routes:

```ts
export const s3 = dimahS3({
  routes: {
    publicMedia: route({
      upload: true,
    }),
    avatar: route({
      guard: requireUserSession, // [!code ++]
      upload: true,
    }),
  },
});
```

</Accordion>

<Accordion title="How does the browser send custom request headers?">

Configure `headers` in `createS3Client`:

```ts
export const s3Client = createS3Client({
  headers: async () => ({
    // [!code ++]
    Authorization: `Bearer ${await getToken()}`, // [!code ++]
  }), // [!code ++]
});
```

</Accordion>

</Accordions>
