Configurare program

Securing Self-Hosted AI APIs

A self-hosted AI API is both a conventional API and an AI-specific attack surface. Secure it in layers: isolate the model runtime, expose only a hardened gateway, authenticate every caller, authorize each action and data retrieval, constrain compute use, and log enough metadata to investigate abuse without storing sensitive prompts by default. Broken object-level authorization, broken authentication, resource exhaustion, misconfiguration, and unsafe downstream API use are all central API risks.

The key principle: do not treat an LLM endpoint as “just internal.” A compromised internal workstation, leaked API key, malicious prompt, or vulnerable integrated service can turn it into a path toward confidential data or privileged actions.

Reference Architecture

text
Caller
|
v
VPN / private network
|
v
API gateway or Nginx
- TLS / mTLS
- OIDC authentication
- Per-client rate and concurrency limits
- Request-size limits
- Audit metadata
|
v
AI API service
- Request schema validation
- Tenant and role authorization
- Prompt/input controls
- RAG permission filtering
- Tool policy enforcement
|
+--> Local LLM runtime (loopback/private subnet only)
+--> Vector database (ACL-filtered)
+--> Approved tools/services (least privilege)

Bind Ollama, vLLM, or another inference runtime to 127.0.0.1 or a private container network. Block direct inbound access to runtime ports such as 11434 or 8000 using host firewalls, security groups, or Kubernetes NetworkPolicy; only the API layer should reach them. vLLM documentation warns that its API key option alone does not secure every endpoint, so defense must include a reverse proxy and network restrictions.

Use OIDC/OAuth2 access tokens for human and application clients, preferably validated at the gateway and again by the API service for high-value operations. Require MFA through the identity provider for administrator access, use short-lived tokens, rotate service credentials, and keep secrets in a vault or workload-identity mechanism rather than code, shell history, or container images. OWASP advises treating login, token, and account-recovery flows as high-risk endpoints that need brute-force protection, and it notes that API keys identify API clients rather than authenticating users.

Authentication answers who is calling. Authorization answers what that caller may do. Enforce authorization for every resource ID, model name, tenant, conversation, uploaded file, RAG collection, tool, and administrative operation—never rely on a route prefix or a client-supplied tenant field. For example, a caller authorized for team-a documents must not obtain team-b vector chunks merely by changing a collection ID; that is the AI equivalent of BOLA.

LLM inference is vulnerable to resource exhaustion because prompts, output length, concurrent requests, file uploads, embeddings, and tool loops consume CPU, GPU VRAM, memory, storage, and money. OWASP classifies this broader problem as unrestricted resource consumption for APIs and unbounded consumption for LLM applications.owasp+1

Apply limits at multiple points:

  • Request body and file-upload size.

  • Maximum prompt tokens and maximum generated tokens.

  • Per-user, per-API-key, and per-IP request rates.

  • Concurrent generation requests and queue depth.

  • Request duration and upstream read timeouts.

  • Embedding batch size and document-ingestion quotas.

  • Tool-call count, recursion depth, execution time, and spend budgets.

  • Tenant-specific monthly quotas and alerts.

Return a controlled 429 or 503 when overloaded; do not let queue growth exhaust host RAM or GPU memory. For longer jobs such as document ingestion, use an asynchronous queue with per-tenant limits rather than holding an API connection open.

Defend Prompts and RAG

Prompt injection happens when user-supplied or retrieved text tries to override the system’s intended behavior; OWASP identifies it as a leading LLM application risk. No prompt wording fully “solves” this, so place security boundaries outside the model’s judgment.

Treat prompts, files, web content, and retrieved RAG chunks as untrusted data. Never let the model decide whether a user is allowed to access a document, call a privileged API, read a secret, or execute a shell command. Instead:

  • Apply ACL filters before vector retrieval.

  • Pass only authorized chunks into the model context.

  • Clearly label retrieved content as untrusted reference text.

  • Require structured tool-call schemas and validate them server-side.

  • Map each tool to a narrowly scoped service account.

  • Require human approval for destructive or externally consequential actions.

  • Allowlist outbound domains and block link-local, loopback, private-address, and cloud-metadata targets for any URL-fetching tool.

Least-privilege tools, approval gates for consequential actions, tool-use auditing, and bounded agent execution are recommended safeguards against excessive agency.

Protect Data and Supply Chain

Classify data before it enters prompts, embeddings, logs, or model files. Redact secrets and sensitive identifiers where possible; encrypt data in transit and at rest; segregate tenants; and define retention/deletion rules for conversations, uploads, embeddings, and backups. Track document and dataset modifications with provenance so a suspicious RAG result can be traced to a source and rolled back.

Pin container images and model versions by digest, scan images and dependencies, restrict who may pull or register models, verify model provenance, and separate the model-download environment from normal inference egress. Do not automatically ingest arbitrary uploads, repositories, webpages, or tickets into a production knowledge base: scan, parse, classify, review, hash, and approve them first. Poisoned RAG documents can manipulate answers or introduce malicious operational guidance.

Monitoring and Testing

Log structured metadata: request ID, authenticated principal, tenant, selected model, endpoint, status, latency, token counts, rate-limit decision, retrieved document IDs, and tool invocations. Avoid recording raw prompts, generated text, authorization headers, secrets, or document contents unless a narrowly approved diagnostic policy requires it.

Test the service like both an API and an AI system:

  • Replay a valid request while swapping tenant, conversation, document, model, and tool IDs to test authorization.

  • Fuzz JSON fields, streaming endpoints, file upload parsers, and model parameters.

  • Test rate limits with parallel requests, long inputs, large max_tokens intentionally slow streaming clients.

  • Attempt prompt injection through direct prompts and indexed documents.

  • Verify RAG ACLs using users from different teams and classifications.

  • Test tools with malicious arguments, SSRF-style URLs, and requests for destructive actions.

  • Confirm that an API key cannot access operational or administrative endpoints outside its intended scope.

For your first hardening task, sketch your own inference service boundary and identify the one component that currently has the broadest privilege—for example, the API gateway, RAG service, tool runner, or model host—then describe the first privilege reduction you would apply.

[mai mult...]

Multi-Agent Workflows with Persistent Memory and Human Gatekeeping

A multi-agent workflow divides a complex task among specialized AI components instead of asking one model to do everything. For example, one agent can collect evidence, another can analyze it, a third can draft an answer, and a final agent can check policy or quality. Persistent memory gives the workflow continuity across sessions, while human gatekeeping ensures that high-impact actions remain under human control.

The central rule is simple: agents may recommend, prepare, classify, and summarize, but they should not independently make irreversible decisions, access sensitive data outside their scope, or execute consequential actions.

Core Architecture

A practical design separates orchestration, agents, memory, tools, and approval controls.

text
User or application
|
v
Workflow orchestrator
|
+--> Research agent
+--> Analysis agent
+--> Drafting agent
+--> Policy and validation agent
|
v
Human approval gate
|
v
Approved action or final response

The orchestrator owns the workflow state. It decides which agent runs next, passes only the required context to that agent, records results, detects failures, and stops the workflow when an approval requirement is reached. Do not let agents communicate freely without control. Unbounded agent-to-agent conversation can create loops, hidden assumptions, duplicated work, and unclear accountability.

An agent should have a narrow responsibility, limited data access, and minimal tools.

  • Research agent: Retrieves approved internal documents, tickets, runbooks, or external evidence.

  • Analysis agent: Compares evidence, identifies gaps, calculates risk, or proposes options.

  • Drafting agent: Produces a report, email, change request, or technical plan.

  • Validation agent: Checks required fields, policy constraints, source references, formatting, and safety rules.

  • Execution agent: Performs an approved action through a narrowly scoped API or automation account.

For example, in an infrastructure incident workflow, the research agent gathers alerts and related runbook sections. The analysis agent determines likely impact. The drafting agent prepares a change proposal. A human approves the proposal. Only then can an execution agent create a ticket, scale a deployment, restart a service, or apply an approved remediation.

This separation makes failures easier to investigate. If a bad recommendation appears, you can determine whether it came from retrieval, reasoning, drafting, validation, or an incorrect approval decision. Persistent memory should not mean storing every conversation forever. Store specific, governed facts that improve future work.

Use three memory types:

  • Working memory: Temporary state for one workflow run, such as task ID, intermediate findings, selected documents, and pending approvals. Delete or expire it when the task finishes.

  • Episodic memory: Records of previous interactions, decisions, approvals, incidents, and outcomes. This supports auditability and allows the system to learn from completed work.

  • Semantic memory: Durable facts such as service ownership, approved procedures, business rules, known environment constraints, and validated technical preferences.

Each stored memory item should include metadata similar to this:

json

{
"memory_id": "mem-2026-000184",
"type": "semantic",
"content": "Production PostgreSQL restore operations require DBA approval.",
"source": "approved-runbook-v4",
"owner": "database-team",
"classification": "internal",
"allowed_roles": ["dba", "platform-admin"],
"created_at": "2026-08-20T12:00:00Z",
"expires_at": null,
"confidence": "verified",
"review_status": "approved"
}

The most important fields are source, owner, classification, allowed roles, freshness, and approval status. An agent should not treat an old chat message as equivalent to an approved runbook or a signed operational decision.

Retrieve Memory Safely

Before an agent receives memory, apply authorization and relevance filtering.

text
1. Identify the user and workflow identity.
2. Resolve the user's roles and permissions.
3. Retrieve only memory allowed for those permissions.
4. Prefer approved, recent, and high-confidence records.
5. Label memory with source and confidence.
6. Give the agent only the minimum necessary context.

Never rely on the model to decide whether the caller may access a memory record. The memory service must enforce that decision before information reaches the prompt.

For a team knowledge base, separate records by tenant, department, project, environment, and classification. A production incident agent should not automatically receive HR records, customer data, credentials, private keys, unrelated security reports, or another team’s confidential project history.

Human gatekeeping is a policy control, not a decorative confirmation button. Define what requires approval in advance.

Require explicit approval for actions such as:

  • Changing production infrastructure or Kubernetes resources.

  • Restarting, scaling, deleting, or reconfiguring services.

  • Sending emails, tickets, messages, or reports outside the system.

  • Accessing sensitive datasets or exporting internal information.

  • Creating credentials, rotating keys, changing IAM roles, or modifying firewall rules.

  • Executing SQL write operations or running potentially destructive commands.

  • Publishing recommendations that affect legal, financial, HR, compliance, or customer decisions.

The approval request should include the proposed action, intended target, expected impact, evidence used, uncertainty level, rollback method, risk level, and exact command or API payload where applicable.

text
Action: Restart deployment inventory-api in production
Reason: All replicas are unhealthy after a failed image rollout
Evidence: Deployment events, readiness probe failures, approved runbook section 4.2
Impact: Brief request interruption possible
Rollback: Roll back to image digest sha256:...
Required approver: Production platform on-call engineer
Status: Pending approval

A human should approve a specific action, not a vague goal. “Fix the deployment” is too broad; “roll back deployment X to image digest Y” is reviewable and auditable.

Control Agent Tools

An LLM should never receive unrestricted shell, Kubernetes, database, cloud, or network access. Give each action agent a dedicated service account with permissions limited to one environment, namespace, service, or operation type.

A safe execution pattern is:

text
Agent proposes structured action
|
v
Policy engine validates target and parameters
|
v
Human approves the exact action
|
v
Executor uses least-privilege service account
|
v
Result is logged and returned to the workflow

Validate tool arguments server-side. If an agent proposes a Kubernetes operation, verify the allowed namespace, resource type, name pattern, operation, image source, and change window before execution. Do not allow free-form shell commands when a structured API operation can be used instead.

Persistent memory introduces risks beyond normal prompt handling.

  • Memory poisoning: A malicious document or user message adds misleading instructions or false facts to long-term memory.

  • Stale memory: An old procedure is retrieved after infrastructure or policy has changed.

  • Cross-tenant disclosure: One user’s information is returned to another team or customer.

  • Over-retention: Sensitive personal, operational, or credential-related data remains longer than necessary.

  • False confidence: The model treats a low-confidence note as an established fact.

Mitigate these risks with approval workflows for durable memory, source provenance, expiration dates, versioning, review queues, audit trails, role-based retrieval filters, and a deletion process. Treat user-provided instructions as untrusted unless they are verified and promoted through a controlled process.

Monitor and Test

Track each workflow through a correlation ID. Log the workflow version, agent invoked, input classification, memory records retrieved, tools requested, policy decisions, human approver, execution result, and final outcome. Avoid logging raw sensitive prompts or secrets unless a specific approved investigation requires it.

Test workflows with realistic failure cases:

  • A malicious memory entry that tells an agent to ignore policy.

  • An expired runbook that conflicts with a newer approved procedure.

  • A user requesting data outside their role.

  • An agent attempting to call an unauthorized tool.

  • A proposed production action with incomplete rollback information.

  • An approval request where the target resource differs from the original task.

  • A failed action that must stop rather than retry indefinitely.

[mai mult...]

Self-Hosted Telegram SysAdmin Bot with Ollama

A Telegram sysadmin bot connects a chat interface to a local LLM and, optionally, to real system operations. The design challenge is not “how do I call the Telegram API,” it is “how do I let a chat message trigger AI reasoning and system actions without creating an unauthenticated remote-control channel into my infrastructure.” Treat this project as an API security exercise wrapped around a convenient chat frontend.

Telegram supports two mutually exclusive update mechanisms: long polling with getUpdates, and webhooks with setWebhook. getUpdates is a pull method where your bot repeatedly asks Telegram’s servers for new messages, and it cannot be used while a webhook is active. setWebhook is a push method: Telegram sends an HTTPS POST containing a JSON Update object to your specified URL whenever a message arrives.core.telegram+1

For a homelab or single-admin bot behind NAT, long polling is simpler because it needs no public inbound port. For a bot exposed through your own domain and reverse proxy, a webhook avoids constant polling and reacts faster. If you switch between the two, call deleteWebhook before starting getUpdates, since Telegram returns a conflict error if both are configured at once.

Long Polling Version

This is the easier starting point for a private admin bot with no public exposure.

python
import time
import requests

TELEGRAM_TOKEN = “YOUR_BOT_TOKEN”
API_BASE = f”https://api.telegram.org/bot{TELEGRAM_TOKEN}“
ALLOWED_CHAT_IDS = {123456789}

def get_updates(offset=None):
params = {“timeout”: 30, “allowed_updates”: [“message”]}
if offset:
params[“offset”] = offset
resp = requests.get(f”{API_BASE}/getUpdates”, params=params, timeout=35)
resp.raise_for_status()
return resp.json()[“result”]

def send_message(chat_id, text):
requests.post(f”{API_BASE}/sendMessage”, json={“chat_id”: chat_id, “text”: text})

def ask_ollama(prompt):
resp = requests.post(
“http://127.0.0.1:11434/api/chat”,
json={
“model”: “llama3.2”,
“messages”: [{“role”: “user”, “content”: prompt}],
“stream”: False,
},
timeout=60,
)
resp.raise_for_status()
return resp.json()[“message”][“content”]

def main():
offset = None
while True:
updates = get_updates(offset)
for update in updates:
offset = update[“update_id”] + 1
message = update.get(“message”)
if not message:
continue
chat_id = message[“chat”][“id”]
if chat_id not in ALLOWED_CHAT_IDS:
continue
text = message.get(“text”, “”)
reply = ask_ollama(text)
send_message(chat_id, reply)
time.sleep(1)

if __name__ == “__main__”:
main()

Ollama’s chat endpoint accepts a model name and a list of role-tagged messages, and returns the model’s reply; setting stream to false gives one complete response object instead of a token stream. The offset parameter in getUpdates must be one greater than the last processed, update_id or Telegram will resend already-handled messages.

If you expose the bot through a domain with a reverse proxy, register the webhook once:

bash
curl -F "url=https://bot.example.internal/telegram/webhook" \
-F "secret_token=YOUR_RANDOM_SECRET" \
"https://api.telegram.org/bot${TELEGRAM_TOKEN}/setWebhook"

Telegram lets you set a secret_token so incoming POST requests carry a header you can verify, confirming the request actually originated from your webhook configuration. Your Nginx layer should terminate TLS and forward only to your bot service, following the same reverse-proxy hardening pattern used for any self-hosted API: private-network binding for the backend, rate limiting, and access logging.

python
from fastapi import FastAPI, Header, HTTPException, Request

app = FastAPI()
WEBHOOK_SECRET = “YOUR_RANDOM_SECRET”

@app.post(“/telegram/webhook”)
async def telegram_webhook(request: Request, x_telegram_bot_api_secret_token: str = Header(None)):
if x_telegram_bot_api_secret_token != WEBHOOK_SECRET:
raise HTTPException(status_code=403, detail=“Invalid secret token”)

update = await request.json()
message = update.get(“message”)
if not message:
return {“ok”: True}

chat_id = message[“chat”][“id”]
if chat_id not in ALLOWED_CHAT_IDS:
return {“ok”: True}

reply = ask_ollama(message.get(“text”, “”))
send_message(chat_id, reply)
return {“ok”: True}

Never skip the secret-token check. Without it, anyone who discovers your webhook URL can submit forged Telegram-shaped JSON payloads directly to your bot.

A sysadmin bot is a privileged interface, so authorization must happen before any AI call or system action, not after. Maintain an explicit allowlist of Telegram chat IDs or user IDs, reject everything else silently or with a generic denial, and log rejected attempts. Do not rely on “security through obscurity” from an unlisted bot username; bot usernames and tokens can leak through screenshots, shared chats, or repository history.

Layer authorization by role if multiple admins use the bot:

json
{
"chat_id": 123456789,
"role": "read-only",
"allowed_commands": ["status", "ask"]
}
{
"chat_id": 987654321,
"role": "operator",
"allowed_commands": ["status", "ask", "restart-service", "run-backup"]
}

Route every command through this permission table before execution. A “read-only” user should never reach a code path that can restart a service or touch a database.

Follow the same separation you’d apply to any AI-driven automation: the model can draft, explain, and suggest, but a structured, validated, allowlisted function should perform any real action. Do not let free-text bot input be interpolated directly into a shell command.

python
ALLOWED_ACTIONS = {
"status": lambda: run_readonly_check("systemctl status nginx"),
"disk": lambda: run_readonly_check("df -h"),
"restart_nginx": lambda: run_privileged_action("systemctl restart nginx"),
}

def handle_command(role, command):
if command not in ALLOWED_ACTIONS:
return “Unknown or unauthorized command.”
if command.startswith(“restart”) and role != “operator”:
return “You do not have permission for this action.”
return ALLOWED_ACTIONS[command]()

Use this pattern instead of asking the LLM to “generate and run whatever shell command answers the question.” Free-form command generation from a chat message is a direct path to remote code execution if the bot, token, or Telegram account is ever compromised.

Protect Secrets and the Runtime

Store the Telegram bot token, webhook secret, and any service credentials in environment variables or a secrets manager, never hardcoded or committed to a repository. Run the bot process under a dedicated, unprivileged Linux user, restrict its filesystem access, and grant it sudo rights only for the exact commands it must run, ideally via a tightly scoped sudoers entry rather than full root access.

Keep Ollama bound to 127.0.0.1 so only the bot process can reach it, matching the same loopback-binding pattern used for any self-hosted inference API. If the bot and Ollama run in separate containers, use an internal Docker network instead of exposing Ollama’s port to the host or LAN.

Log every command with timestamp, chat ID, role, command name, and outcome, but avoid logging full LLM prompts or responses by default if users might paste sensitive infrastructure details. Add a simple in-memory or Redis-backed rate limiter per chat ID to prevent one user or a compromised token from flooding Ollama with requests or triggering repeated privileged actions.

python
from collections import defaultdict
import time

_last_call = defaultdict(float)
MIN_INTERVAL_SECONDS = 3

def rate_limited(chat_id):
now = time.time()
if now – _last_call[chat_id] < MIN_INTERVAL_SECONDS:
return True
_last_call[chat_id] = now
return False

[mai mult...]

Cum pot primi notificări pe Slack pentru e-mailurile urgente din Gmail fără să folosesc cod?

Verificarea constantă a inbox-ului pentru e-mailuri urgente (de la un anumit client, manager sau cu un anumit subiect) consumă foarte mult timp și scade productivitatea. Există o metodă prin care pot automatiza acest proces, astfel încât să primesc o alertă instantanee pe Slack doar pentru mesajele prioritare, fără să fie nevoie să scriu scripturi sau să folosesc API-uri prin cod?

[mai mult...]

Workaround pentru optimizarea spatiului pe un server windows

Identificarea problemei, unde se duce spatiul.

In powershell ca admin:

Vedere rapidă — top foldere mari (PowerShell)

# Top 20 foldere pe C:\ sortate dupa dimensiune
Get-ChildItem C:\ -Recurse -ErrorAction SilentlyContinue |
  Where-Object { -not $_.PSIsContainer } |
  Group-Object DirectoryName |
  Select-Object Name, @{N='MB';E={[math]::Round(($_.Group | Measure-Object Length -Sum).Sum/1MB,1)}} |
  Sort-Object MB -Descending |
  Select-Object -First 20 |
  Format-Table -AutoSize

Verifică rapid fișierele sistem mari ascunse
# Fisiere sistem mari: pagefile, hiberfil, swapfile
Get-Item -Path C:\pagefile.sys, C:\hiberfil.sys, C:\swapfile.sys `
  -Force -ErrorAction SilentlyContinue |
  Select-Object Name, @{N='GB';E={[math]::Round($_.Length/1GB,2)}}

# Dimensiune WinSxS (raportata — include hardlink-uri, nu e exacta)
"{0:N2} GB" -f ((Get-ChildItem C:\Windows\WinSxS -Recurse -Force `
  -ErrorAction SilentlyContinue | Measure-Object Length -Sum).Sum / 1GB)
Foldere de loguri și alte spatii cunoscute ca mari

1C:\Windows\Logs\CBS\ — loguri Component-Based Servicing (update-uri)

2C:\ProgramData\Microsoft\Windows\WER\ReportQueue\ — crash reports în așteptare

3C:\ProgramData\Microsoft\Windows\WER\ReportArchive\ — rapoarte arhivate

4C:\Windows\SoftwareDistribution\Download\ — update-uri descărcate de Windows Update

5C:\Windows\Temp\ și %TEMP% — fișiere temporare sistem și utilizator

6C:\inetpub\logs\LogFiles\ — loguri IIS (pot ajunge la zeci de GB pe servere web)

7C:\Windows\memory.dmp — kernel memory dump complet (egal cu RAM-ul serverului)

Pagefile tipic
8–64 GB
Hiberfil.sys
= RAM
WinSxS tipic
5–25 GB
Kernel dump
= RAM

 [mai mult...]