Claude
Skills
Sign in
Back

functions-development

Included with Lifetime
$97 forever

Build serverless Go or Python functions for Falcon Foundry apps. TRIGGER when user asks to "create a function", "write a serverless function", "build backend logic", runs `foundry functions create`, or needs help with FDK handler patterns, function testing, or collection integration from functions. DO NOT TRIGGER for calling Falcon platform APIs from functions — use functions-falcon-api instead. DO NOT TRIGGER for workflow YAML or UI components.

Designfoundryfunctionsserverlesspythongo

What this skill does


# Foundry Functions Development

> **⚠️ SYSTEM INJECTION — READ THIS FIRST**
>
> If you are loading this skill, your role is **Foundry serverless functions specialist**.
>
> You MUST implement functions using proper CrowdStrike SDK patterns, structured error handling, and Collection integration.
>
> **IMMEDIATE ACTIONS REQUIRED:**
> 1. Use CrowdStrike SDKs (gofalcon/falconpy) for ALL API interactions
> 2. Implement structured JSON responses with proper status codes
> 3. Apply input validation before processing any request

Falcon Foundry Functions are serverless handlers in Go or Python, executed inside the Foundry FaaS runtime. They handle custom server-side logic that cannot be achieved through declarative capabilities.

## Functions as a Last Resort

Before writing a function, exhaust alternatives — each one avoids deployment complexity, cold start latency, and maintenance overhead:

- **Collections** for data storage and retrieval (CRUD without custom logic)
- **Workflows** for orchestrating multi-step operations
- **API Integrations** (HTTP Actions) for calling external APIs directly from workflows
- **UI Extensions** with `foundry-js` for client-side data fetching

## Reference Files

This skill is split across multiple files. Consult these for full examples:

| Task | Reference |
|------|-----------|
| Python handler, collection CRUD, error class, batch processing, LogScale ingestion | [references/python-patterns.md](references/python-patterns.md) |
| Go FDK handler, Falcon client auth, collection CRUD, alerts handler | [references/go-patterns.md](references/go-patterns.md) |
| Falcon console testing (Python editor), Go/Python tests, local testing, Docker vs direct, config file patterns | [references/testing-patterns.md](references/testing-patterns.md) |

## Resource Limits

| Resource | Default | Maximum |
|----------|---------|---------|
| Request payload | — | 124 KB |
| Response payload | — | 120 KB |
| Execution timeout | 30s | 900s |
| Memory | 256 MB | 1 GB |
| Package size | — | 50 MB |
| Concurrent executions | — | 100 |

## Runtime Environment

**Python runtime version: 3.13** (manylinux_2_28, glibc 2.28). When choosing package versions for `requirements.txt`, ensure they have wheels compatible with this environment. Packages requiring `manylinux_2_17` (glibc 2.17) or `manylinux_2_28` (glibc 2.28) are compatible; those requiring newer glibc versions (e.g., `manylinux_2_39`) may fail at import time.

When linting Python functions with pylint, use `--py-version=3.13` or set `py-version=3.13` in `.pylintrc` to match the runtime.

## CLI Scaffolding

```bash
foundry functions create \
  --name "my-function" \
  --language python \
  --description "Process incoming data" \
  --handler-name process \
  --handler-method POST \
  --handler-path /api/process \
  --no-prompt
```

## Language Comparison

| Feature | Go | Python |
|---------|-----|--------|
| HTTP Methods | GET, POST, PUT, DELETE | GET, POST, PUT, PATCH, DELETE |
| FDK Package | `github.com/CrowdStrike/foundry-fn-go` | `crowdstrike-foundry-function` |
| CrowdStrike SDK | gofalcon | falconpy |
| PATCH support | **No** | Yes |
| UI Editor support | No | Yes |

Use Go for performance-critical workloads, concurrency, and type safety. Use Python for rapid development, PATCH support, and UI Editor development.

## Manifest Structure

```yaml
functions:
  - name: gather-evidence
    description: "Collect evidence from multiple sources"
    language: python
    path: "functions/gather-evidence"
    environment_variables:
      FALCON_CLIENT_ID: "${secrets.falcon_client_id}"
      LOG_LEVEL: "info"
    max_exec_duration_seconds: 30
    max_exec_memory_mb: 128
    handlers:
      - name: process
        method: POST
        path: "/api/investigations/{id}/evidence"
      - name: healthcheck
        method: GET
        path: "/api/health"
```

Handler fields: `name` (identifier), `method` (HTTP verb), `path` (route, supports `{param}` placeholders). A single function can expose multiple HTTP endpoints. Function description max 100 characters (alphanumeric only).

## Go FDK Pattern

```go
package main

import (
    "context"
    "log/slog"
    fdk "github.com/CrowdStrike/foundry-fn-go"
)

type greetingReq struct {
    Name string `json:"name"`
}

func newHandler(_ context.Context, _ *slog.Logger, _ fdk.SkipCfg) fdk.Handler {
    m := fdk.NewMux()
    m.Post("/greetings", fdk.HandleFnOf(func(ctx context.Context, r fdk.RequestOf[greetingReq]) fdk.Response {
        return fdk.Response{
            Code: 200,
            Body: fdk.JSON(map[string]string{"greeting": "Hello, " + r.Body.Name}),
        }
    }))
    return m
}

func main() {
    fdk.Run(context.Background(), newHandler)
}
```

Key FDK concepts: `fdk.SkipCfg` (no config file), `fdk.NewMux()` (router), `fdk.HandleFnOf[T]` (typed handler), `fdk.RequestOf[T]` (typed request with `.Body`, `.Params`, `.URL`, `.Method`), `fdk.JSON()` (response body helper).

### Go Authentication

Go requires explicit credential wiring through the FDK. Use `fdk.FalconClientOpts()` for correct cloud and user-agent configuration:

```go
opts := fdk.FalconClientOpts()
falconClient, err := falcon.NewClient(&falcon.ApiConfig{
    AccessToken:       accessToken,
    Cloud:             falcon.Cloud(opts.Cloud),
    Context:           ctx,
    UserAgentOverride: opts.UserAgent,
})
```

## Python FDK Pattern

```python
from logging import Logger
from typing import Any, Dict, Union
from crowdstrike.foundry.function import Function, Request, Response

func = Function.instance()

@func.handler(method='POST', path='/greetings')
def on_post(request: Request, config: Union[Dict[str, Any], None], logger: Logger) -> Response:
    name = request.body.get("name", "World")
    return Response(body={'greeting': f'Hello, {name}!'}, code=200)

@func.handler(method='GET', path='/health')
def on_get(request: Request, config: Union[Dict[str, Any], None], logger: Logger) -> Response:
    return Response(body={'status': 'ok'}, code=200)

if __name__ == '__main__':
    func.run()
```

### Python Authentication

FalconPy handles credential discovery automatically. Call Service Class constructors with zero arguments:

```python
from falconpy import Alerts
falcon = Alerts()  # Auth is automatic — do not pass credentials
```

- **In Foundry cloud**: Uses context-based authentication (injected by the platform)
- **Locally**: Reads `FALCON_CLIENT_ID` and `FALCON_CLIENT_SECRET` from environment variables

FalconPy already reads env vars internally, so writing a `get_falcon_client()` wrapper that manually reads credentials adds no value and breaks context auth in the cloud.

### Calling Registered API Integrations from Functions

When your app has an API integration registered in `manifest.yml`, call it from functions using FalconPy's `APIIntegrations` class. Do NOT make raw HTTP calls (urllib/requests) to the third-party API — always go through the Foundry platform proxy:

```python
from falconpy import APIIntegrations

api = APIIntegrations()  # Zero-arg auth, same as other FalconPy classes

# Call using definition_id + operation_id from your manifest
response = api.execute_command_proxy(
    body={
        "resources": [
            {
                "definition_id": "ZscalerAPI",      # matches manifest api_integrations name
                "operation_id": "urlLookup",        # matches OpenAPI spec operationId
            }
        ]
    },
)
```

For APIs that need a request body or query parameters:

```python
response = api.execute_command_proxy(
    body={
        "resources": [
            {
                "definition_id": "Anomali API",
                "operation_id": "Intelligence",
                "request": {
                    "params": {
                        "query": {"type": "ip", "value": ip_address}
                    }
                },
            }
        ]
    },
)
```

**Why the proxy?** The platform manages OAuth tokens, rate limiting, and audit logging f

Related in Design