# Security Considerations for k-skill: A Defense-in-Depth Analysis

> Explore security considerations for k-skill. Discover defense-in-depth strategies including API secret protection, environment isolation, sandboxing, and CI controls.

- Repository: [NomaDamas/k-skill](https://github.com/NomaDamas/k-skill)
- Tags: deep-dive
- Published: 2026-08-04

---

**The k-skill project adopts a defense-in-depth security model that protects API secrets through environment-variable isolation, runtime sandboxing, and strict CI controls.**

This open-source skill ecosystem (NomaDamas/k-skill) connects independent "skills" to public and free APIs. Because many integrations require authentication tokens, the codebase implements layered protections to prevent credential exposure while maintaining developer flexibility. This guide examines the specific security mechanisms built into the proxy server, browser runtime, and continuous integration pipeline.

## Secret Handling Through Environment Variables

Hard-coded credentials are strictly prohibited throughout k-skill. All sensitive values flow through `process.env`, falling back to safe defaults when absent.

In [`packages/k-skill-proxy/src/server.js`](https://github.com/NomaDamas/k-skill/blob/main/packages/k-skill-proxy/src/server.js), the proxy base URL resolves through a priority chain that never exposes secrets in source files:

```javascript
function getProxyBaseUrl(options = {}) {
  // Uses explicit option, then env var, then defaults
  return (
    options.proxyBaseUrl ||
    process.env.KSKILL_PROXY_BASE_URL ||
    "https://k-skill-proxy.nomadamas.org"
  );
}

```

Similarly, Data.go.kr API keys and other provider credentials follow identical patterns. If an environment variable is missing, the code defaults to an empty string or safe placeholder rather than failing open.

## Free-API Proxy Policy and Attack Surface Reduction

The `k-skill-proxy` package enforces a strict routing policy documented in [`docs/deploy-k-skill-proxy.md`](https://github.com/NomaDamas/k-skill/blob/main/docs/deploy-k-skill-proxy.md). **Public endpoints without authentication requirements are called directly from the user's machine**, bypassing the proxy entirely.

This design limits proxy traffic to only those free APIs that mandate key-based authentication—such as Data.go.kr—preventing unnecessary request centralization and reducing DDoS exposure. The proxy layer also implements:
- Configurable rate limiting via environment variables
- Optional caching layers to prevent API abuse
- No credential storage in logs or response bodies

## Runtime Isolation with k-skill-browser-runtime

Skills requiring browser automation depend on [`packages/k-skill-browser-runtime/src/provider.js`](https://github.com/NomaDamas/k-skill/blob/main/packages/k-skill-browser-runtime/src/provider.js). This abstraction prevents direct Chrome DevTools Protocol (CDP) manipulation and isolates each skill's session context.

The provider selection logic reads from `KSKILL_BROWSER_PROVIDER` without exposing the resolved value:

```javascript
function resolveProvider(env = process.env) {
  const provider = env.KSKILL_BROWSER_PROVIDER || "auto";
  return String(provider).trim();
}

```

This isolation prevents:
- Cross-skill cookie leakage
- Authentication token persistence between sessions
- Accidental credential spills through shared browser state

## CI Security Controls and Secret Scrubbing

The GitHub Actions workflow in [`.github/workflows/ci.yml`](https://github.com/NomaDamas/k-skill/blob/main/.github/workflows/ci.yml) executes `npm run ci` in a clean environment. Tests that require temporary credentials follow a strict injection-and-cleanup pattern demonstrated in [`packages/public-restroom-nearby/test/index.test.js`](https://github.com/NomaDamas/k-skill/blob/main/packages/public-restroom-nearby/test/index.test.js):

```javascript
test("public restroom search uses API key", async () => {
  const original = process.env.KAKAO_REST_API_KEY;
  process.env.KAKAO_REST_API_KEY = "dummy-key";
  await runSearch();               // skill code reads the env var
  process.env.KAKAO_REST_API_KEY = original; // restore immediately
});

```

**Critical CI security practices include:**
- No persistent secrets in the test environment
- Immediate environment variable restoration post-test
- No credential retention in CI logs

## Dependency Safety and Auditability

The repository leverages npm workspaces and Changesets for version management, eliminating manual version pinning that could introduce vulnerable dependencies. Each skill publishes a [`skill.json`](https://github.com/NomaDamas/k-skill/blob/main/skill.json) manifest declaring required permissions—such as login requirements—enabling downstream consumers to audit data access risks before installation.

## Summary

- **Environment-only secrets**: All credentials resolve through `process.env` with safe defaults in [`server.js`](https://github.com/NomaDamas/k-skill/blob/main/server.js) and provider configurations.
- **Selective proxy routing**: Free APIs without keys bypass the proxy; authenticated traffic routes through rate-limited, non-logging infrastructure.
- **Browser sandboxing**: `k-skill-browser-runtime` abstracts CDP connections and isolates per-skill sessions via [`provider.js`](https://github.com/NomaDamas/k-skill/blob/main/provider.js).
- **Ephemeral CI credentials**: Tests inject and immediately clear API keys, preventing secret persistence in logs or long-running processes.
- **Manifest-based permissions**: [`skill.json`](https://github.com/NomaDamas/k-skill/blob/main/skill.json) files document required access levels for ecosystem auditability.

## Frequently Asked Questions

### How does k-skill prevent API key leaks in source code?

The codebase enforces a strict policy: **no hard-coded credentials**. Every sensitive value reads from environment variables like `process.env.DATA_GO_KR_API_KEY` or `process.env.KSKILL_PROXY_BASE_URL`, defaulting to empty strings or safe fallbacks when unset. This pattern appears consistently in [`server.js`](https://github.com/NomaDamas/k-skill/blob/main/server.js) and throughout the monorepo.

### Is the k-skill-proxy safe to expose publicly?

The proxy intentionally restricts traffic to **free APIs requiring authentication keys**. Public endpoints are excluded from proxy routing, reducing the attack surface. Additionally, the server implements rate limiting, optional caching, and never logs or returns credentials in HTTP responses.

### What prevents browser-based skills from leaking session data?

The `k-skill-browser-runtime` package in [`provider.js`](https://github.com/NomaDamas/k-skill/blob/main/provider.js) abstracts all CDP connections. Each skill receives an isolated browser context—cookies and tokens do not persist across invocations, and the `KSKILL_BROWSER_PROVIDER` environment variable controls provider selection without exposing sensitive configuration values.

### How are secrets handled during continuous integration?

CI pipelines in [`.github/workflows/ci.yml`](https://github.com/NomaDamas/k-skill/blob/main/.github/workflows/ci.yml) run without persistent secrets. When tests require credentials, they temporarily inject values into `process.env`, execute the test, and **immediately restore the original value**—preventing secret retention in logs or environment dumps.