kosa8 docs

Guides / kosa8 Cloud / Security Center

Security Center

The Security Center is one page in the kosa8 Cloud dashboard (Access → Security Center at app.kosa8.com), the same thing in the CLI (kosa8 cloud security, agents, freeze, siem, evidence) and a Cloud Security panel in the desktop app's Account view. It reads your organization's own settings, API keys and audit log. It does not certify anything: the checklist is a self-check for you to act on, and the evidence file is your own record for your own review or your auditor's.

Posture checklist

Each check passes, fails, or does not apply, and names the dashboard page that changes it. The score is the number that pass out of the number that apply, for example 7 / 12. There is no letter grade.

CheckPasses when
Single sign-on is connectedAn OIDC connection is set up (Team & SSO).
Dashboard sign-in requires SSO“Require SSO for the dashboard” is on.
An email domain is verifiedAt least one SSO domain is verified by its DNS TXT record.
A named person is an ownerAt least one member has the owner role, so the org is not run only from a shared admin key.
Few people hold owner or adminOwners plus admins are at most half the members, or at most two. Does not apply with no members.
At most 2 live admin keysNo more than two unrevoked, unexpired API keys have the admin scope.
No key older than 90 daysEvery live key was made (or rotated) in the last 90 days.
No key unused for 30 daysEvery live key was used, or made, in the last 30 days.
Non-admin keys have an end dateEvery live key without admin has an expiry.
A monthly spending cap is setSettings has a spending cap.
The audit log's hash chain verifiesGET /v1/audit/verify finds no edited, removed or reordered event.
The audit log left kosa8 in the last 30 daysAn NDJSON export or an evidence export in the last 30 days, or a working SIEM destination.
The audit log streams to a SIEMAt least one SIEM destination whose last delivery succeeded.

Not checked, and said so on the page: kosa8 Cloud has no built-in multi-factor sign-in (require SSO and use your identity provider's MFA), and no org-wide egress policy setting yet.

curl -s https://api.kosa8.com/v1/security/posture -H "Authorization: Bearer $KOSA8_API_KEY"
# {"score":{"passed":7,"total":12},"frozen":false,"items":[{"id":"sso_connected","area":"Identity",
#   "title":"Single sign-on is connected","ok":false,"detail":"…","fix":{"tab":"team","label":"Set up SSO"}},…]}

Reading it needs the owner or admin role, or a key with audit:read.

Agent inventory

Every API key (an agent's, a CI job's or a person's) and every member, with its scopes or role, its state (active, suspended, expired, revoked), when it was last used, and the sandboxes and functions it made. Who made what comes from the audit log's successful sandbox.create, sandbox.fork and function.deploy events; anything made before the audit log, or by a key revoked more than 30 days ago, is listed as unattributed. Revoke ends a key at once through the usual DELETE /v1/api-keys/{id}.

$ kosa8 cloud agents
$ kosa8 cloud agents --revoke key_…

Kill switch: freeze the organization

An owner or admin can freeze the organization, for example when a key may have leaked or an agent is doing something it should not. You type the organization's name to confirm (the CLI asks for it unless you pass --yes). A freeze:

While frozen, reads and incident response still work: revoking keys, adding, demoting or removing members, changing SSO and settings, deleting or sleeping sandboxes, deleting functions and webhooks, and the Security Center itself. Function invocations already running when the freeze lands are not cut short.

Unfreezing restores the keys the freeze suspended, unless you ask it not to. Sandboxes stay asleep until woken; their next command wakes them. Both actions are in the audit log as security.freeze and security.unfreeze, with the reason, how many keys were suspended or restored and how many sandboxes were put to sleep; every refused call is recorded too.

curl -s -X POST https://api.kosa8.com/v1/security/freeze -H "Authorization: Bearer $KOSA8_API_KEY" \
  -H 'Content-Type: application/json' -d '{"confirm":"Acme Inc","reason":"key in a public repo","suspend_keys":true}'
curl -s -X POST https://api.kosa8.com/v1/security/unfreeze -H "Authorization: Bearer $KOSA8_API_KEY" \
  -H 'Content-Type: application/json' -d '{"confirm":"Acme Inc"}'   # "restore_keys":false keeps them suspended
$ kosa8 cloud freeze --reason "key in a public repo" --suspend-keys
$ kosa8 cloud unfreeze

SIEM streaming

Every audit event, in order, to up to five destinations per organization. The minute tick sends the events after each destination's cursor, up to 100 per request and 500 per minute, and moves the cursor only when the destination answers 2xx. A failure is retried after 1, 5 and 15 minutes, then hourly, and the stream resumes where it stopped: no event is skipped. Redirects are not followed, and URLs must be public https. Owners and admins manage destinations.

KindRequest
webhookPOST of {"org_id","destination_id","events":[…]} with Kosa8-Signature: t=<unix s>,v1=<hex HMAC-SHA256(secret, "<t>.<body>")>, as the event webhooks sign. The whsec_… secret is shown once.
splunk_hecYour HEC URL with Authorization: Splunk <token>; one {"time","host","source","sourcetype","index"?,"event"} object per line. sourcetype defaults to ocsf:api_activity.
datadoghttps://http-intake.logs.<site>/api/v2/logs with DD-API-KEY; a JSON array of {"ddsource":"kosa8","service":"kosa8-cloud","message","ocsf"}. Sites: datadoghq.com, us3, us5, datadoghq.eu, ap1, ap2, ddog-gov.com.

Tokens and API keys are stored encrypted and never returned by the API. Each event is OCSF API Activity (class_uid 6003, category_uid 6): activity_id from the action's verb (1 create, 2 read, 3 update, 4 delete, 99 other), status_id 2 with status_code for a refused call, time, actor.user (a member, an API key or the system), api.operation (the audit action, e.g. sandbox.exec), resources, and metadata.uid org:seq. kosa8 Cloud does not record client IP addresses, so src_endpoint carries only the channel (key, session, sso, system). The original event, its detail and its chain hashes are in unmapped.

curl -s -X POST https://api.kosa8.com/v1/security/siem -H "Authorization: Bearer $KOSA8_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"kind":"splunk_hec","url":"https://splunk.example.com:8088/services/collector/event","token":"…","index":"security"}'
# start: "beginning" (default, sends the whole log first) or "now"
curl -s -X POST https://api.kosa8.com/v1/security/siem/siem_…/test -H "Authorization: Bearer $KOSA8_API_KEY"
$ KOSA8_SIEM_TOKEN=… kosa8 cloud siem add --kind datadog --site datadoghq.eu
$ kosa8 cloud siem ls
$ kosa8 cloud siem test siem_…

Evidence export

Download evidence (or kosa8 cloud evidence export, or GET /v1/security/evidence?since=&until=) saves one JSON file: the posture checklist, the audit chain's verification, and the audit events in the range (default the last 90 days, at most 20,000 events, with truncated set past that).

{"content":{"format":"kosa8.evidence.v1","statement":"…","org":{…},"range":{…},"posture":{…},
  "audit":{"chain":{"ok":true,…},"count":412,"truncated":false,"events":[…]}},"sha256":"9f2c…"}

sha256 is the SHA-256 of content as served: canonical JSON, object keys sorted and no spaces, the same form the audit chain hashes. The CLI checks it before saving. To check it yourself:

python3 -c 'import json,hashlib,sys; f=json.load(open(sys.argv[1]));
c=json.dumps(f["content"],sort_keys=True,separators=(",",":"),ensure_ascii=False);
print(hashlib.sha256(c.encode()).hexdigest()==f["sha256"])' kosa8-evidence-….json

Each export is recorded in the audit log as security.evidence_export, with its hash. The file is generated by kosa8 Cloud from your organization's own data; it is not a certification, an attestation or an audit opinion.

API

RouteScope
GET /v1/security/postureaudit:read
GET /v1/security/inventoryaudit:read
GET /v1/security/evidenceaudit:read
GET /v1/security/freezeany key of the org
POST /v1/security/freeze, /unfreezeadmin (owners and admins)
GET, POST /v1/security/siem, DELETE /v1/security/siem/{id}, POST …/{id}/testadmin