What you will be able to do
- Add stored procedures, UDFs and external functions that follow the owner's-rights and import-path rules
- Configure a default Streamlit UI or a container web endpoint, and the container privileges an app requests
- Share provider data with an app through the package, including data that lives outside it
- Request access to consumer objects through references instead of hard-coded names
- Set DISTRIBUTION correctly and keep separate development and production packages
1.Application logic: procedures, UDFs and external functions
A Native App can include stored procedures, user-defined functions and external functions, written in any language Snowflake supports. Snowpark libraries are supported for procedures in Java, Scala and Python. Every one of these objects is defined in the app's setup script. Python code must use a supported runtime, because Native Apps don't support decommissioned Python versions. That limit applies to new versions and to installing existing ones.
The key security fact is how the code runs. Every procedure and UDF runs as the application itself and can reach every object in the installed app. That is why every procedure must be EXECUTE AS OWNER. A caller's-rights procedure would let a consumer write code that reads or changes the app's internals and its shared data. Because the code runs with this much access, Snowflake recommends bound parameters for any SQL built from user input, including procedure arguments, to prevent SQL injection.
Code can also live in files. Referenced files, such as JARs and Python modules, belong to a specific version and are imported by procedures and UDFs. Resource files, such as a machine learning model, go on a named stage the package can read. Any procedure, UDF or external function that imports these files must be created in a versioned schema, and the import path starts with / and is relative to the version root, the directory that holds the manifest.
CREATE FUNCTION app_code.add(x INTEGER, y INTEGER)
RETURNS INTEGER
LANGUAGE JAVA
HANDLER = 'TestAddFunc.add'
IMPORTS = ('/JARs/Java/TestAddFunc.jar');Checkpoint 1 of 7· Check yourself
A provider wants a stored procedure in their app to run with the consumer's privileges so that it can query whatever the calling user can see. What does the framework allow?
Procedures in a Native App must use owner's rights. Caller's rights would let consumer code act as the app and reach its internal objects and shared data.
“must be run with the rights of the owner (EXECUTE AS OWNER).”Source: docs.snowflake.com
Checkpoint 2 of 7· Exam question
A provider is deciding which manifest_version to declare for a new Native App. What is the key practical difference between manifest_version 1 and manifest_version 2 that the provider must account for?
Correct answer: A — manifest_version 2 enables automated privilege granting, which carries security implications the provider must evaluate before adopting it
- A. Manifest version 2 introduces automated granting of certain requested privileges during install, which reduces friction but also means privileges can be granted without an explicit consumer click, so it must be evaluated carefully.
- B. The setup script remains required in both manifest versions; manifest_version 2 does not eliminate it or move logic into the manifest file itself.
- C. Container-based artifacts are not restricted to manifest_version 1; the version distinction is about privilege-granting behavior, not container support.
- D. Requested privileges are still declared in the manifest's privileges section under both versions; manifest_version 2 does not move this to the listing profile.
Sources1
2.User interfaces: Streamlit or a container endpoint
An app can include a Streamlit app as its user interface. The manifest names which one opens by default with default_streamlit under artifacts, giving the schema-qualified Streamlit object. Context functions behave differently inside a Streamlit app in a Native App. For example, CURRENT_USER returns NULL unless the app has been granted READ SESSION ON ACCOUNT.
artifacts:
...
default_streamlit: app_schema.streamlit_app_na
...An app with containers uses Snowpark Container Services. Its manifest lists each container image under artifacts.container_services.images, as /<database>/<schema>/<image_repository>/<image_name>:tag, with one entry per image. Instead of a Streamlit UI, it can set default_web_endpoint with a service and an endpoint. That endpoint must also be defined in the service specification file. An app can set only one of these two defaults.
Two privileges are specific to apps with containers. CREATE COMPUTE POOL lets the app create a compute pool in the consumer account, and it isn't needed if the consumer creates the pool manually. BIND SERVICE ENDPOINT is needed for an endpoint to be reachable from outside Snowflake. The provided documentation doesn't describe the compute pool's own settings, such as sizing. Remember the earlier rule as well: Snowpark Container Services objects can't go in a versioned schema, so they belong in a regular schema.
artifacts:
readme: readme.md
setup_script: setup.sql
container_services:
images:
- /dev_db/dev_schema/dev_repo/image1
- /dev_db/dev_schema/dev_repo/image2
default_web_endpoint:
service: ux_schema.ux_service
endpoint: ui
privileges:
- CREATE COMPUTE POOL:Checkpoint 3 of 7· Check yourself
A container app's consumers will create the compute pool themselves, but the app's UI endpoint must be reachable from outside Snowflake. Which privilege must the manifest request?
CREATE COMPUTE POOL is unnecessary when the consumer creates the pool manually. External access to an endpoint needs BIND SERVICE ENDPOINT.
“This privilege is required to allow an endpoint to be accessible outside of Snowflake.”Source: docs.snowflake.com
3.Bundling provider data and keeping boundaries
The application package carries data content as well as logic, so the provider has to decide which data ships with the app. Objects that the setup script creates stay private to the app. Provider data reaches the app only when it is shared through the package. When you share an object this way, you must also share the schema that contains it. Views can be shared the same way.
Data that lives outside the application package can't be shared with the installed app directly. Instead, the provider grants REFERENCE_USAGE on the outside database to the package's share. Next, they create a view inside the package that selects from the outside table, and then grant USAGE on the view's schema and SELECT on the view to the share. Only the view crosses the boundary, not the underlying database.
GRANT REFERENCE_USAGE ON DATABASE other_db
TO SHARE IN APPLICATION PACKAGE app_pkg;Shared data also changes how policies behave. In shared content, several context functions return null, including CURRENT_ROLE, CURRENT_USER and CURRENT_WAREHOUSE. A row access policy that relies on them won't work as it does in the provider's own account. Even when it does run, a username like CURRENT_USER's can exist in more than one account.
Checkpoint 4 of 7· Check yourself
A provider wants an app to read a lookup table in a provider database that isn't part of the application package. What is the supported approach?
Objects outside the package can't be shared directly. REFERENCE_USAGE plus a view inside the package is the documented route.
“You cannot share objects outside the application package directly with app installed in the consumer account.”Source: docs.snowflake.com
4.References to consumer objects and external dependencies
The opposite case is an app that needs a consumer's existing object, such as a table in one of their databases. A plain grant isn't enough, because the app can't know the schema and object names in the consumer account ahead of time. References solve this: the consumer names the object and allows access to it.
On the provider side, there are three steps. First, decide which objects need references and which privileges they need. Then define the references in the manifest file. Finally, add a stored procedure to the setup script that handles the callback for each reference. The consumer side runs in a fixed order after installation, as the check below tests.
A related dependency rule goes the other way. A setup script shouldn't create objects outside the app that point to objects inside it. For example, a view in an outside database that reads an app table breaks when the consumer drops the app. This applies to tables, procedures, UDFs and references.
Checkpoint 5 of 7· Put it in order
Put the consumer's steps for granting an app access to one of their tables in order
- 1.Run the app's callback stored procedure, passing the reference id
- 2.View the references the app requires
- 3.Create the reference by calling SYSTEM$REFERENCE
The consumer first sees what the app asks for, then creates the reference, then gives it to the app through the provider's callback procedure.
“Create the reference by calling the SYSTEM$REFERENCE system function.”Source: docs.snowflake.com
5.Distribution modes and separate dev and production packages
The DISTRIBUTION property controls the kinds of listing a package can back. INTERNAL allows only private listings inside the organization that created the package, and it skips the automated security scan. EXTERNAL allows listings outside that organization, including private listings to other organizations, public listings and Marketplace listings. You can set the property when you create the package or change it later. If it is set at creation, every version or patch added afterwards is scanned immediately. In Snowsight, the same choice appears as distributing to accounts outside or inside your organization.
Snowflake's recommended setup uses two packages. A development package set to INTERNAL lets developers iterate quickly without starting a security review on every change. A production package set to EXTERNAL receives only versions that have passed the provider's own review, and it goes to Snowflake for scanning and to external consumers. This keeps experimental work away from the version that paying consumers run.
A separate package setting, MULTIPLE_INSTANCES = TRUE, lets a consumer install up to 30 instances of an app. Once it is set, it can't be turned off.
Checkpoint 6 of 7· Fill the gap
This is the production package of a two-package setup, intended for Marketplace consumers. Which value completes the statement?
CREATE APPLICATION PACKAGE hello_snowflake_package
DISTRIBUTION = ? ;Listings outside the organization, including Marketplace listings, require DISTRIBUTION = EXTERNAL, which also triggers the security scan.
Source: docs.snowflake.comCheckpoint 7 of 7· Exam question
What is the primary role of the setup script within a Snowflake Native App application package?
Correct answer: A — It contains the SQL statements executed to create the objects (procedures, functions, roles, views) that make up the app when it is installed or upgraded
- A. The setup script is a SQL script executed during install or upgrade that creates the app's internal objects, such as procedures, functions, views, and application roles, inside the application object.
- B. Declaring artifacts, privileges, and references is the job of manifest.yml, not the setup script, which is purely SQL that builds objects.
- C. The setup script does not store compiled binaries; container images are pushed separately to an image repository and referenced by the service specification.
- D. Version and patch history is tracked by the application package's metadata and release channels, not written into the setup script itself.
Exam traps
Each one states something that sounds right. Open it to see what is actually true.
1.Procedures in a Native App can use caller's rights so that they respect the consumer user's own privileges.Why is that wrong?
Every procedure the app creates or runs must be EXECUTE AS OWNER, and it runs as the application with access to all of the app's objects.
Covered in Application logic: procedures, UDFs and external functions
2.A container app can declare both a default Streamlit app and a default web endpoint and let the consumer pick.Why is that wrong?
The manifest accepts only one of default_web_endpoint and default_streamlit.
Covered in User interfaces: Streamlit or a container endpoint
3.Every version and patch is security-scanned, even in a package used only inside the organization.Why is that wrong?
The automated scan doesn't run when DISTRIBUTION is INTERNAL. That is why the development package uses INTERNAL.
Covered in Distribution modes and separate dev and production packages
Sources
Every claim above is drawn from one of these pages, quoted as it was written on the date shown.
- 1.
“The Snowflake Native App Framework allows you to include stored procedures, user-defined functions (UDFs), and external functions in an application package.”
↩︎ Application logic: procedures, UDFs and external functions“Snowflake recommends that all SQL commands requiring input from users be run using bound parameters.”
↩︎ Application logic: procedures, UDFs and external functions“that references these types of code files must be created within a versioned schema in the setup script.”
↩︎ Application logic: procedures, UDFs and external functions“Snowflake Native Apps do not support decommissioned versions of Python.”
↩︎ Application logic: procedures, UDFs and external functions“CURRENT_USER returns NULL when invoked from Streamlit in Snowflake.”
↩︎ User interfaces: Streamlit or a container endpoint“Use caution when using context functions in policies applied to shared data content within a Snowflake Native App.”
↩︎ Bundling provider data and keeping boundaries“run as the application and have access to all objects within the installed Snowflake Native App. This can lead to SQL injection attacks.”
↩︎ Exam trap 1“must be run with the rights of the owner (EXECUTE AS OWNER).”
↩︎ Checkpoint - 2.
“To specify the default Streamlit app launched by your app, add the following entries in the manifest file:”
↩︎ User interfaces: Streamlit or a container endpoint - 3.
“It is not required if the consumer creates the compute pool manually.”
↩︎ User interfaces: Streamlit or a container endpoint“If this property is specified, the endpoint must also be defined in the service specification file.”
↩︎ User interfaces: Streamlit or a container endpoint“Only one of the default_web_endpoint and default_streamlit can be specified.”
↩︎ Exam trap 2“This privilege is required to allow an endpoint to be accessible outside of Snowflake.”
↩︎ Checkpoint - 4.
“When adding a shared object to an application package, you must also share the schema that contains the object.”
↩︎ Bundling provider data and keeping boundaries“providers must create views in the application package that allow access the object”
↩︎ Bundling provider data and keeping boundaries“You cannot share objects outside the application package directly with app installed in the consumer account.”
↩︎ Checkpoint - 5.
“the app cannot determine the name of the schema and object in the consumer account.”
↩︎ References to consumer objects and external dependencies“Add a stored procedure in the setup script to handle the callback for each reference defined in the manifest file.”
↩︎ References to consumer objects and external dependencies“Create the reference by calling the SYSTEM$REFERENCE system function.”
↩︎ Checkpoint - 6.
“Do not create objects outside the app that refer to objects within the app.”
↩︎ References to consumer objects and external dependencies - 7.
“INTERNAL indicates that a provider can only create a private listing within the same organization where the application package was created.”
↩︎ Distribution modes and separate dev and production packages“any versions or patches added to the application package later are scanned immediately.”
↩︎ Distribution modes and separate dev and production packages“The automated security scan is not performed when the DISTRIBUTION property is set to INTERNAL.”
↩︎ Exam trap 3 - 8.
“Snowflake recommends creating two separate application packages:”
↩︎ Distribution modes and separate dev and production packages“developers can quickly make changes and test new features without triggering the security review process for each iteration.”
↩︎ Distribution modes and separate dev and production packages - 9.
“consumers can install a maximum of 30 instances of the app in their account.”
↩︎ Distribution modes and separate dev and production packages