# Shared schema (AIRLOCK_DATA.SHARED): Creating and granting access

Airlock can validate spec data against **customer-defined views** in a dedicated schema, `AIRLOCK_DATA.SHARED`. The schema lives in your account. The **app does not grant** USAGE or CREATE VIEW on this schema to any application role. You (the customer) control who can create and use views there by granting privileges with a role that has permission to grant on the schema (typically **SECURITYADMIN** or the role that owns the database).

---

## 1. Ensure the schema exists

The app can create the schema for you so it exists after install or setup:

```sql
CALL airlock.admin.create_shared_schema();
```

This creates `AIRLOCK_DATA.SHARED` if it does not exist. It does **not** grant any privileges. If your deployment already creates this schema (e.g. via a different setup script), you can skip this step.

---

## 2. Grant USAGE and CREATE VIEW to roles that need them

Use a role that can grant on the schema (e.g. **SECURITYADMIN**, or the role that owns `AIRLOCK_DATA`). Grant **USAGE** on the schema so a role can reference it; grant **CREATE VIEW** so the role can create or replace views in that schema.

**Example: grant to the Airlock app_admin application role**

```sql
GRANT USAGE ON SCHEMA AIRLOCK_DATA.SHARED TO APPLICATION ROLE app_admin;
GRANT CREATE VIEW ON SCHEMA AIRLOCK_DATA.SHARED TO APPLICATION ROLE app_admin;
```

**Example: grant to a custom role**

If you use a custom role (e.g. `AIRLOCK_ADMIN_CUSTOM`) that is used to run Airlock admin operations:

```sql
GRANT USAGE ON SCHEMA AIRLOCK_DATA.SHARED TO ROLE AIRLOCK_ADMIN_CUSTOM;
GRANT CREATE VIEW ON SCHEMA AIRLOCK_DATA.SHARED TO ROLE AIRLOCK_ADMIN_CUSTOM;
```

**Example: grant only USAGE (read-only) to a role that should query views but not create them**

```sql
GRANT USAGE ON SCHEMA AIRLOCK_DATA.SHARED TO APPLICATION ROLE app_user;
-- Optionally grant SELECT on specific views (see Snowflake docs).
```

You can grant to whichever roles you want; Airlock does not require any specific role to have these privileges.

**FK validation:** Procedures run with **EXECUTE AS OWNER** and must be able to **read** the view to validate foreign-key rules. Grant **SELECT** on each shared view to the application (recommended in Native App) or to the role that owns the application package:

```sql
-- Recommended: grant to the application so OWNER can read the view
GRANT SELECT ON VIEW AIRLOCK_DATA.SHARED.employees TO APPLICATION <your_application_name>;

-- Alternative: grant to the role that runs procedures
GRANT SELECT ON VIEW AIRLOCK_DATA.SHARED.employees TO ROLE <owner_role>;
```

Without SELECT on the view, `validate_data` will fail when checking FK rules (e.g. "not authorized" or object not found).

---

## 3. Create views (standard SQL)

After a role has USAGE and CREATE VIEW on `AIRLOCK_DATA.SHARED`, that role can create views with standard SQL:

```sql
CREATE OR REPLACE VIEW AIRLOCK_DATA.SHARED.employees AS
SELECT id, name, email FROM my_db.my_schema.employee_table;
```

Then register the view with Airlock as a **reference** so it can be used in spec FK rules:

```sql
-- Legacy: shared-view-only registration
CALL airlock.admin.register_shared_view('SHARED', 'employees', PARSE_JSON('["email"]'));

-- Preferred: unified reference registration (view-backed reference)
CALL airlock.admin.register_reference(
  'employees_ref',
  'shared_view',
  'SHARED',
  'employees',
  NULL,
  PARSE_JSON('["email"]')
);
```

See the [Airlock Stored Procedure Reference](airlock-api-v1.md) shared schema / references section and the stored procedure contract for the full workflow.
