Data science teams hold some of the most sensitive data in an organisation and run arbitrary code against it every day, usually outside the controls that apply to production software. A notebook server is a remote code execution service by design, a downloaded model file can run code when it is loaded, and a shared training extract can hold more personal data than the system it came from. This guide is for data scientists, ML engineers, analytics leads and the security staff who support them. It covers daily habits and team controls for notebooks, credentials, datasets, model artefacts and sharing, with a rollout plan, metrics and framework mapping. It is about the security duties of every data science team; if you are interested in applying data science to security as a career, see the Security Data Scientist Career Guide instead.
Source note: technical behaviour below is summarised from the Jupyter, Python, PyTorch, Hugging Face, GitHub, ICO, NCSC and MITRE sources listed in the references, as checked in November 2026. Confirm against the official text before relying on it.
Key takeaways
- A notebook server is code execution. Jupyter's own documentation states that access to the server means access to running arbitrary code, so authentication and network exposure are not optional settings.
- Model files can be programs. Pickle-based checkpoints execute code at load time; prefer safetensors and restricted loading, and only load artefacts from sources you trust.
- Notebooks leak secrets. Keys pasted into cells and printed outputs end up in Git history, shared drives and exported HTML; keep credentials out of notebooks entirely.
- Extracts are copies of production data. Minimise, pseudonymise and expire them, and keep the re-identification key away from the analysis copy.
- Sharing links are credentials. Signed URLs and storage tokens used to share data or models need the narrowest scope, read-only access and a short expiry.
Why data science work carries different risk
Production software passes through code review, CI pipelines and change control. Exploratory data science often does not: notebooks run on laptops or shared servers, pull data straight from warehouses with personal credentials, install packages on demand and save outputs wherever is convenient. The result is a set of risks that general awareness training rarely covers.
| Asset | Typical risk | Habit that prevents it |
|---|---|---|
| Notebook server (Jupyter, JupyterHub, hosted notebooks) | Anyone who reaches the server can run code as the user, with the user's data and cloud access | Keep token or password authentication on, bind to localhost or sit behind SSO, never expose a personal server to the internet |
| Notebook files (.ipynb) | API keys and connection strings in cells; sensitive rows in saved outputs | Load credentials from the environment or a secrets manager; clear outputs before committing or sharing |
| Training and analysis datasets | Uncontrolled copies of production personal data on laptops and buckets | Minimise columns, pseudonymise, set a deletion date, store in approved locations only |
| Model artefacts (checkpoints, weights) | Malicious pickle files run code on load; models can memorise training data | Prefer safetensors, use restricted loading, load from trusted publishers, track provenance |
| Packages and environments | Typosquatted or compromised packages steal credentials at install time | Pin versions, use an internal mirror or approved index, review new dependencies |
| Sharing links and storage tokens | Over-scoped, long-lived links expose whole storage accounts | Scope to the object, read-only, short expiry, dedicated storage for public data |
Notebook servers: authentication and exposure
The Jupyter Server security documentation is direct: access to the server means access to running arbitrary code, so access must be restricted. Token authentication is enabled by default and the token is printed at start-up. Setting both c.ServerApp.token = "" and c.ServerApp.password = "" turns authentication off, which the documentation marks as not recommended unless another layer handles access control. Teams disable it to avoid typing a token, then reach the server through a port forward or a cloud VM with a public IP, and the result is an unauthenticated remote shell holding warehouse credentials.
- Personal servers: keep the default token or set a password with
jupyter server password, bind to localhost, and reach remote VMs through SSH tunnelling or the platform's authenticated proxy rather than an open port. - Shared servers: use JupyterHub or a managed notebook platform with the organisation's SSO and MFA, one account per person, and no shared logins. Jupyter's authorisation layer (
ServerApp.authorizer_class) is off by default, meaning every authenticated user can read, write and execute, so separate users at the platform level. - Kernel traffic: Jupyter Server 2.20 added kernel transport encryption (
KernelManager.transport_encryption, default'disabled', with'auto'and'required'options using CurveZMQ). Consider it where kernels run on separate hosts from the server. - Untrusted notebooks: Jupyter tracks notebook trust with signatures stored in
nbsignatures.dband never runs untrusted JavaScript output. Opening a notebook is not the same as running it: read a notebook from an unknown source before executing its cells, because running a cell runs its code with your access.
For server hardening detail, see the Jupyter Server Security Guide.
Credentials in notebooks and pipelines
Data science work needs credentials: warehouse logins, cloud storage keys, LLM API keys, Databricks or Snowflake tokens. The habit that causes most leaks is pasting a key into a cell "just for now". The cell is saved, committed, exported to HTML for a stakeholder, or synced to a shared drive. LLM API keys are a common target because stolen keys convert directly into spend; see the LLMjacking Guide.
- Never type a secret into a cell. Read it from an environment variable set by the platform, a secrets manager client, or the notebook platform's secret store. See the Secrets Management Guide.
- Prefer short-lived, identity-based access. Use SSO-backed warehouse connections and cloud workload identity on managed compute instead of static access keys.
- Separate personal and pipeline identities. Scheduled jobs and model training pipelines should run as dedicated service principals with only the data they need, not as the data scientist who built them. See the Databricks Service Principals and Token Security Guide for one platform's approach.
- Clear outputs before sharing. Printed DataFrames, tracebacks and environment dumps put data and secrets into the file. Strip outputs before commit with a pre-commit hook, and review exported HTML before sending it.
- Scan repositories and history. GitHub secret scanning covers the full Git history on all branches; similar scanners exist for other platforms. If a key is found, rotate it first: GitHub's guidance notes that removing it from history is time-consuming and often unnecessary once it is revoked. See How to find secrets in Jupyter notebooks.
Datasets: minimise, pseudonymise, expire
An analysis extract is a new copy of production data with weaker controls. Treat requests for data as you would a request for access to the source system.
- Minimise columns and rows: request only the fields the question needs. Direct identifiers (names, emails, account numbers) are rarely needed for modelling. See the Data Minimisation Guide.
- Pseudonymise and separate the key: the UK ICO states that pseudonymised data is still personal data in the hands of someone who holds the additional information. It advises storing that additional information separately (a different database or network segment), restricting and logging access to it, and encrypting it. In practice the data engineering team holds the lookup table and the data science team works on tokens. The ICO notes this guidance is under review following the Data (Use and Access) Act. See the Pseudonymisation Techniques Guide.
- Label and locate: every dataset gets a classification, an owner, a purpose and a deletion date, and lives only in approved storage (the governed lakehouse or workspace, not personal cloud drives or laptop downloads). See the Data Classification Guide.
- Expire extracts: set lifecycle rules on scratch buckets and workspace folders so abandoned extracts are deleted automatically.
- Watch what goes into third-party AI tools: pasting sample rows into a public chatbot to "help write the query" is a disclosure. Use approved, contracted AI services for any data above public.
Training data is also an exposure. In 2025 researchers found 11,908 live secrets in a Common Crawl archive used to train large language models; see the 12,000 Live Secrets in LLM Training Data case. Scan scraped and internal corpora for credentials and personal data before training, because a model can reproduce what it saw.
Model artefacts: loading files safely
The Python documentation warns that the pickle module is not secure and that malicious pickle data can execute arbitrary code during unpickling. Many model formats (PyTorch .bin and .pt files, scikit-learn and joblib dumps) are pickle underneath. Hugging Face's security documentation explains how this works and states that its Hub pickle import scan, which lists imports without executing the file, is not foolproof and that users remain responsible for checking files.
| Format or loader | Executes code on load? | Team guidance |
|---|---|---|
| safetensors | No: stores tensors and metadata only | Default format for sharing and storing weights |
PyTorch torch.load with weights_only=True | Restricted to tensors, primitives, dictionaries and types registered with add_safe_globals() | Keep the default True (as shown in current PyTorch documentation); never switch it off for third-party files |
PyTorch torch.load with weights_only=False | Yes: full unpickling | Only for files your own pipeline produced and stored with integrity controls |
| Raw pickle, joblib, cloudpickle | Yes | Internal use only; never load from email, chat, forums or unknown repositories |
- Trust the publisher, not the file name: Hugging Face advises loading files only from trusted users and organisations and notes that signed commits verify origin, not that a file is safe.
- Record provenance: for each model in use, record the source, version or commit hash, file hashes, licence and the datasets used for fine-tuning. Store approved models in an internal registry and load from there. See the Model and Dataset Registry Security guide and the AI Supply Chain and AI-BOM Guide.
- Isolate first loads: load a new third-party model for the first time in a sandbox with no credentials and no network egress, not on a workstation signed in to the data warehouse.
- Protect training integrity: poisoned training data or fine-tuning sets can plant backdoors (OWASP LLM04:2025 Data and Model Poisoning). Restrict who can write to training datasets and keep versioned, hashed copies. See the AI Data Poisoning and Backdoors Guide.
Sharing data and models outside the team
The Microsoft SAS Token Exposure 2023 is the clearest data science lesson on record. An AI research team published open-source models on GitHub with a download link containing an Azure SAS token. The token was scoped to the whole storage account with full control rather than to the model files, and its expiry had been extended to 2051. About 38TB of internal data, including workstation backups and Teams messages, was reachable for roughly three years.
- Scope: share the object or container, never the account. For Azure, prefer user delegation SAS or service SAS with a stored access policy so links can be revoked. See the Azure SAS Tokens Security Guide.
- Permission: read-only by default; write or delete permissions on a shared link are almost never needed.
- Expiry: hours or days, not years. Re-issue rather than extend.
- Separation: publish public datasets and models from dedicated storage that holds nothing else.
- Triage: when a scanner flags a URL with a token, treat it as a live credential until proven otherwise.
Packages and environments
Data science environments install more third-party packages than most application teams, often with pip install directly from a notebook cell. Malicious packages on public indexes routinely target cloud and API credentials at install time.
- Pin and lock: use lock files (pip-tools, Poetry, conda-lock or uv) and rebuild environments from them, rather than installing ad hoc in a running kernel.
- Use an approved index: point pip and conda at an internal mirror or proxy that can block known-malicious packages and enforce a short delay on newly published versions.
- Check names: typosquats of popular libraries are common; copy package names from official documentation.
- Base images: build team images centrally with scanned, approved packages so individual data scientists start from a known state.
See the Malicious Package and Dependency Confusion Guide.
Where identity fits
Most data science access is non-human in practice: notebook tokens, warehouse service accounts, pipeline service principals, API keys for model providers and storage SAS tokens. Each should have an owner, a purpose, the smallest data scope and an expiry, and should be listed in the same inventory as other machine identities. When a data scientist leaves, revoke the personal tokens they created and transfer pipeline ownership; jobs that silently keep running on a departed user's token are a common finding. See the MLOps Security Guide for the pipeline side.
Implementation roadmap
- Weeks 1 to 2, inventory: list notebook servers (including cloud VMs running Jupyter), workspaces, scratch buckets, model stores and the credentials the team uses. Run a secret scan across team repositories and shared notebook folders.
- Weeks 3 to 4, quick fixes: rotate any exposed keys, turn authentication back on for any server running without it, close public notebook ports, and set lifecycle deletion on scratch storage.
- Month 2, safe defaults: move secrets to the platform secret store, add an output-stripping and secret-scanning pre-commit hook to team repositories, and publish an approved package index. Pilot with one team for two weeks, gather friction points, then roll out.
- Month 3, data and models: introduce dataset request records (purpose, fields, deletion date), pseudonymisation for modelling extracts, a model provenance record and safetensors as the default format.
- Ongoing: include these habits in role-based training for new starters and review exceptions quarterly. Roll back any control that breaks a critical workflow by granting a time-limited, logged exception rather than switching the control off for everyone.
Small and large teams: a two-person analytics team can get most of the value from a managed notebook platform with SSO, the platform secret store and a pre-commit hook. A large organisation with many data science groups should add a central model registry, an internal package proxy, platform-enforced data access policies and a security champion in each group.
Detection and measurement
- Secrets in notebooks: count of secret scanning findings in notebook files per month, and median hours from detection to rotation.
- Exposed servers: number of notebook servers reachable from the internet or running without authentication, found by external attack surface scans; target zero.
- Extract hygiene: percentage of analysis datasets with an owner, classification and deletion date.
- Safe model formats: share of models in the registry stored as safetensors or loaded with restricted loading.
- Static keys: number of long-lived personal access tokens and storage keys used by scheduled jobs, trending down as workload identity replaces them.
Log and alert on: new public sharing links or account-level SAS tokens on data science storage, large exports from the warehouse to personal locations, and use of team API keys from unexpected networks.
Framework mapping
| Team practice | NIST SP 800-53 Rev 5 | NIST CSF 2.0 | AI-specific references |
|---|---|---|---|
| Restrict notebook and data access | AC-2, AC-6 | PR.AA-05 | NCSC secure AI guidelines: secure deployment |
| Credentials out of notebooks | IA-5 | PR.AA-05 | MITRE ATT&CK T1552.001 Credentials In Files |
| Dataset inventory and protection | SC-28 | ID.AM-07, PR.DS-01 | MITRE ATLAS AML.T0025 Exfiltration via Cyber Means |
| Safe model loading and provenance | SR-3, SR-4, SI-7 | GV.SC-05 | MITRE ATLAS AML.T0010 AI Supply Chain Compromise, AML.T0011.000 Unsafe AI Artifacts; OWASP LLM03:2025 Supply Chain |
| Training data integrity | SI-7 | PR.DS-01 | MITRE ATLAS AML.T0020 Poison Training Data; OWASP LLM04:2025 |
| Approved packages and images | CM-7, SR-3 | PR.PS-06 | MITRE ATT&CK T1195.002 Compromise Software Supply Chain |
| Monitoring data movement | AU-2 | PR.DS-01 | NCSC secure AI guidelines: secure operation |
Common failure patterns
- Authentication turned off for convenience: a Jupyter server started with an empty token on a cloud VM, reachable by anyone who finds the port.
- The key in cell 3: an API key pasted into a notebook, committed, then forked or exported; deleting the cell later does not remove it from history.
- Loading a model from a forum link: a pickle checkpoint loaded with full unpickling on a workstation signed in to production data.
- The account-wide sharing link: a storage token meant for one model folder that grants full control of everything, as in the Microsoft SAS Token Exposure 2023.
- Immortal extracts: a full customer table copied for a one-off analysis two years ago and still sitting in a scratch bucket.
- Pipelines on personal tokens: a production scoring job that breaks, or keeps running unowned, when its creator leaves.
Practitioner checklist
The checklist below sets out NHI Mgmt Group recommendations, drawn from the sources cited on this page.
- Confirm every notebook server requires authentication and none is exposed to the internet.
- Move all credentials out of notebooks into a secrets manager or platform secret store.
- Add output stripping and secret scanning to team repositories as a pre-commit step.
- Rotate any key found in a notebook, export or Git history, then decide whether to clean history.
- Require a purpose, owner, classification and deletion date for every analysis extract.
- Pseudonymise modelling extracts and keep the lookup table with a separate team.
- Make safetensors the default model format and keep
weights_only=Truefor third-party files. - Record provenance and hashes for every model in use and load from an internal registry.
- Scope sharing links to objects, read-only, with short expiry, from dedicated storage.
- Run scheduled jobs as service principals, not as individual data scientists.
Standards and references
- NCSC: Guidelines for secure AI system development
- Project Jupyter: Security in the Jupyter Server
- Python Software Foundation: pickle, Python object serialization
- PyTorch: torch.load
- Hugging Face: Pickle Scanning
- ICO: Pseudonymisation
- OWASP: Top 10 for LLM Applications 2025
- MITRE ATLAS: AI Supply Chain Compromise
Related NHI Mgmt Group resources: MLOps Security Guide · Jupyter Server Security Guide · Secrets Management Guide · Security for Product Managers Guide