onenote-security-basics
Implement secure authentication, token management, and permission scoping for OneNote Graph API. Use when hardening OneNote integrations, implementing least-privilege permissions, or managing token lifecycle. Trigger with "onenote security", "onenote permissions", "onenote token management", "onenote least privilege".
What this skill does
# OneNote Security Basics
## Overview
OneNote Graph API security changed fundamentally on March 31, 2025, when Microsoft deprecated app-only authentication for OneNote endpoints. Every integration must now use delegated authentication through MSAL, which means real users must sign in — no more background service accounts with client secrets. This skill covers the full security surface: permission scoping, token lifecycle management, MSAL cache serialization, credential storage, and multi-tenant hardening. Get any of these wrong and your integration either breaks silently (expired tokens returning 401s) or over-provisions access (Notes.ReadWrite.All when Notes.Read suffices).
## Prerequisites
- Azure AD app registration with redirect URI configured at https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps
- Microsoft 365 license (E3/E5/Business) with OneNote enabled
- Python: `pip install msgraph-sdk azure-identity msal` or Node: `npm install @microsoft/microsoft-graph-client @azure/identity @azure/msal-node`
- Understanding of OAuth 2.0 authorization code flow and delegated permissions
## Instructions
### Permission Scope Matrix
Choose the minimum scope required for your use case:
| Scope | Read notebooks | Read pages | Create pages | Create notebooks | Admin consent? |
|-------|:-:|:-:|:-:|:-:|:-:|
| `Notes.Read` | Yes | Yes | No | No | No |
| `Notes.ReadWrite` | Yes | Yes | Yes | Yes | No |
| `Notes.ReadWrite.All` | Yes | Yes | Yes | Yes | **Yes** |
| `Notes.Create` | No | No | Yes | Yes | No |
**Least-privilege recommendations:**
- Read-only dashboards: `Notes.Read` (user consent only)
- Personal note creation: `Notes.ReadWrite` (user consent only)
- Cross-user/organizational access: `Notes.ReadWrite.All` (requires tenant admin approval)
- Write-only ingestion: `Notes.Create` (cannot read back what was written)
### Delegated Authentication Setup (Post-2025 Mandatory)
**CRITICAL:** App-only authentication (ClientSecretCredential) was deprecated for OneNote endpoints on March 31, 2025. All code below uses delegated auth exclusively.
**Python — Device Code Flow (headless/CLI environments):**
```python
from azure.identity import DeviceCodeCredential
from msgraph import GraphServiceClient
import os
CLIENT_ID = os.environ["AZURE_CLIENT_ID"]
TENANT_ID = os.environ["AZURE_TENANT_ID"]
# Minimal scopes — only request what you need
scopes = ["Notes.ReadWrite"]
credential = DeviceCodeCredential(
client_id=CLIENT_ID,
tenant_id=TENANT_ID,
# cache_persistence_options enables silent token renewal
)
client = GraphServiceClient(credentials=credential, scopes=scopes)
```
**TypeScript — Interactive Browser Flow (web apps):**
```typescript
import { DeviceCodeCredential } from "@azure/identity";
import { Client } from "@microsoft/microsoft-graph-client";
import { TokenCredentialAuthenticationProvider }
from "@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials";
const credential = new DeviceCodeCredential({
clientId: process.env.AZURE_CLIENT_ID!,
tenantId: process.env.AZURE_TENANT_ID!,
});
const scopes = ["Notes.ReadWrite"];
const authProvider = new TokenCredentialAuthenticationProvider(credential, { scopes });
const client = Client.initWithMiddleware({ authProvider });
```
### Token Lifecycle Management
Access tokens expire after **1 hour**. Refresh tokens last **90 days** but can be revoked by admin policy. Your code must handle silent renewal:
```python
# Python: MSAL token cache serialization for persistent sessions
import msal
import json
import os
CACHE_FILE = os.path.expanduser("~/.onenote-token-cache.json")
def get_msal_app():
cache = msal.SerializableTokenCache()
if os.path.exists(CACHE_FILE):
cache.deserialize(open(CACHE_FILE).read())
app = msal.PublicClientApplication(
client_id=os.environ["AZURE_CLIENT_ID"],
authority=f"https://login.microsoftonline.com/{os.environ['AZURE_TENANT_ID']}",
token_cache=cache,
)
return app, cache
def acquire_token(app, cache):
accounts = app.get_accounts()
if accounts:
# Silent renewal — no user interaction needed if refresh token valid
result = app.acquire_token_silent(
scopes=["https://graph.microsoft.com/Notes.ReadWrite"],
account=accounts[0],
)
if result and "access_token" in result:
save_cache(cache)
return result["access_token"]
# Fallback: device code flow requires user interaction
flow = app.initiate_device_flow(
scopes=["https://graph.microsoft.com/Notes.ReadWrite"]
)
print(flow["message"]) # "Go to https://microsoft.com/devicelogin..."
result = app.acquire_token_by_device_flow(flow)
save_cache(cache)
return result.get("access_token")
def save_cache(cache):
if cache.has_state_changed:
with open(CACHE_FILE, "w") as f:
f.write(cache.serialize())
os.chmod(CACHE_FILE, 0o600) # Owner-only read/write
```
### Secure Credential Storage
Never store client IDs or tenant IDs in source code. Use environment variables at minimum, Azure Key Vault for production:
```bash
# Development: .env file (add to .gitignore FIRST)
echo ".env" >> .gitignore
cat > .env << 'EOF'
AZURE_CLIENT_ID=your-app-registration-client-id
AZURE_TENANT_ID=your-directory-tenant-id
EOF
chmod 600 .env
```
```python
# Production: Azure Key Vault integration
from azure.keyvault.secrets import SecretClient
from azure.identity import DefaultAzureCredential
vault_url = "https://your-vault.vault.azure.net"
kv_client = SecretClient(vault_url=vault_url, credential=DefaultAzureCredential())
client_id = kv_client.get_secret("onenote-client-id").value
tenant_id = kv_client.get_secret("onenote-tenant-id").value
```
### Multi-Tenant Security Considerations
For apps serving multiple organizations:
- Register as a multi-tenant app (set `supportedAccountTypes` to `AzureADMultipleOrgs`)
- Validate the `tid` (tenant ID) claim in every token — reject tokens from unexpected tenants
- Store per-tenant token caches separately (never mix tenant tokens)
- Handle Conditional Access policies: catch `claims` challenge in 401 responses and re-authenticate with the required claims
### Security Checklist for Production
- [ ] Using delegated auth (NOT app-only/ClientSecretCredential — deprecated March 2025)
- [ ] Minimum required scopes (Notes.Read unless writes needed)
- [ ] Token cache file has 0600 permissions (owner-only)
- [ ] MSAL cache serialized to disk for silent renewal
- [ ] Client ID and tenant ID sourced from environment or Key Vault
- [ ] .env file in .gitignore
- [ ] Token claims validated (aud, tid, exp)
- [ ] Refresh token rotation monitored (90-day expiry alert)
- [ ] Admin consent obtained for Notes.ReadWrite.All (if needed)
- [ ] Conditional Access error handling implemented
## Output
After applying this skill, your OneNote integration will have: least-privilege permission scoping matched to actual usage, persistent MSAL token cache with silent renewal, secure credential storage using environment variables or Key Vault, and a verified security checklist. Authentication failures will produce actionable error messages instead of silent 401 loops.
## Error Handling
| Error | Cause | Fix |
|-------|-------|-----|
| `AADSTS65001: user needs to consent` | Scope not yet granted by user | Redirect to consent URL or use admin consent endpoint |
| `AADSTS700016: app not found` | Wrong client ID or wrong tenant | Verify AZURE_CLIENT_ID matches portal registration |
| `AADSTS50076: MFA required` | Conditional Access policy | Use InteractiveBrowserCredential (device code cannot handle MFA prompts) |
| `403 Forbidden` on OneNote calls | Missing Notes.* permission or using app-only auth | Check scope in token; switch to delegated auth |
| `401 Unauthorized` after working | Access token expired, silent renewal failed | Check refresh token validity; re-serialize cache |
| Token cache file empty afteRelated in Backend & APIs
jfrog
IncludedInteract with the JFrog Platform via the JFrog CLI and REST/GraphQL APIs. Use this skill when the user wants to manage Artifactory repositories, upload or download artifacts, manage builds, configure permissions, manage users and groups, work with access tokens, configure JFrog CLI servers, search artifacts, manage properties, set up replication, manage JFrog Projects, run security audits or scans, look up CVE details, query exposures scan results from JFrog Advanced Security, manage release bundles and lifecycle operations, aggregate or export platform data, or perform any JFrog Platform administration task. Also use when the user mentions jf, jfrog, artifactory, xray, distribution, evidence, apptrust, onemodel, graphql, workers, mission control, curation, advanced security, exposures, or any JFrog product name.
cupynumeric-migration-readiness
IncludedPre-migration readiness assessor for porting NumPy to cuPyNumeric. Use BEFORE substantial porting work begins when the user asks whether code will scale on GPU, whether they should migrate to cuPyNumeric, which NumPy patterns transfer cleanly, what must be refactored before porting, or mentions pre-port assessment, scaling analysis, or refactor planning. Inspect the user's source code, look up NumPy usage, cross-reference the cuPyNumeric API support manifest, and distinguish distributed-scaling-friendly patterns from blockers such as unsupported APIs, scalar synchronization, host round-trips, Python/object-heavy control flow, shape/data-dependent branching, and in-place mutation hazards. Produce a verdict of READY, LIGHT REFACTOR, SIGNIFICANT REFACTOR, or NOT RECOMMENDED, with concrete refactor pointers.
alibabacloud-data-agent-skill
IncludedInvoke Alibaba Cloud Apsara Data Agent for Analytics via CLI to perform natural language-driven data analysis on enterprise databases. Data Agent for Analytics is an intelligent data analysis agent developed by Alibaba Cloud Database team for enterprise users. It automatically completes requirement analysis, data understanding, analysis insights, and report generation based on natural language descriptions. This tool supports: discovering data resources (instances/databases/tables) managed in DMS, initiating query or deep analysis sessions, real-time progress tracking, and retrieving analysis conclusions and generated reports. Use this Skill when users need to query databases, analyze data trends, generate data reports, ask questions in natural language, or mention "Data Agent", "data analysis", "database query", "SQL analysis", "data insights".
token-optimizer
IncludedReduce OpenClaw token usage and API costs through smart model routing, heartbeat optimization, budget tracking, and native 2026.2.15 features (session pruning, bootstrap size limits, cache TTL alignment). Use when token costs are high, API rate limits are being hit, or hosting multiple agents at scale. The 4 executable scripts (context_optimizer, model_router, heartbeat_optimizer, token_tracker) are local-only — no network requests, no subprocess calls, no system modifications. Reference files (PROVIDERS.md, config-patches.json) document optional multi-provider strategies that require external API keys and network access if you choose to use them. See SECURITY.md for full breakdown.
resend-cli
IncludedUse this skill when the task is specifically about operating Resend from an AI agent, terminal session, or CI job via the official resend CLI: installing/authenticating the CLI, sending/listing/updating/cancelling emails, batch sends, domains and DNS, webhooks and local listeners, inbound receiving, contacts, topics, segments, broadcasts, templates, API keys, profiles, or debugging Resend CLI/API failures. Trigger on mentions of Resend CLI, `resend`, `resend doctor`, `resend emails send`, `resend domains`, `resend webhooks listen`, `resend emails receiving`, or agent-friendly terminal automation.
alibabacloud-odps-maxframe-coding
IncludedUse this skill for MaxFrame SDK development and documentation navigation on Alibaba Cloud MaxCompute (ODPS). Helps answer MaxFrame API, concept, official example, and supported pandas API questions; create data processing programs; read/write MaxCompute tables; debug jobs (remote or local); and build custom DPE runtime images. Trigger when users mention MaxFrame, MaxCompute with MaxFrame, ODPS table processing, DPE runtime, MaxFrame docs/examples, DataFrame/Tensor operations, or GPU runtime setup. Works for both English and Chinese queries about Alibaba Cloud data processing with MaxFrame.