Skip to content

IAM-tilgangspolicyer ​

En tilgangspolicy gir eller nekter en maskinprincipal — en API-nøkkel eller en Workload Identity-binding — tillatelse til å kalle Frostmoln-API-et. Den er Frostmolns motstykke til en AWS IAM-policy, GCP IAM eller Azure RBAC, men skrevet i Frostmolns eget vokabular.

En policy lar deg uttrykke minste privilegium som en flat scope-liste ikke kan: en enkelt operasjon i stedet for alle compute:write, én ressurs, et kilde-IP-område, et tidsvindu — og eksplisitt deny. For eksempel: en CI-nøkkel som kan opprette instanser, men aldri slette dem; en Terraform-nøkkel som bare virker fra kontornettet ditt; en SDK-nøkkel som bare kan berøre ressurser merket env=staging.

Mennesker får rettighetene sine fra organisasjonsroller — se Organisasjonsmedlemmer & roller om de fire rollene, eierskapet og hvordan tenants, grupper og guardrails kombineres. Denne siden handler om maskin-sporet.

Hvem forfatter policyer ​

Tilgangspolicyer styrer maskin-principaler, men de forfattes av et menneske innlogget med OIDC (portalen, fm-CLI-en etter fm login, eller Terraform med en OIDC-basert provider). En API-nøkkel eller et workload-identity-token kan ikke opprette, endre eller knytte til en policy — styringsplanet kan aldri låses ute av en policy det selv er underlagt. Dette er bevisst: selv en deny *-policy på din egen nøkkel er gjenopprettbar, fordi du fikser den som et menneske.

Slik fungerer evalueringen ​

Evalueringen er default-deny:

  1. Hvis en deny-regel matcher, nektes forespørselen — en eksplisitt deny vinner alltid, uavhengig av regelrekkefølge eller hvilken policy den kom fra.
  2. Ellers, hvis en allow-regel matcher, tillates forespørselen.
  3. Ellers nektes forespørselen (implisitt deny).

En forespørsel matcher en regel når dens operasjon matcher en av regelens operations, dens mål-FRN matcher en av regelens targets, og alle regelens constraints holder.

Policy-dokumentet ​

En policy er et JSON-dokument: en schemaVersion og en liste med rules.

json
{
  "schemaVersion": "1",
  "rules": [
    {
      "name": "compute-read-only",
      "access": "allow",
      "operations": ["compute:instances:read", "compute:instances:list"],
      "targets": ["frn:compute:*:*:instances/*"]
    }
  ]
}

Hver regel har disse feltene:

FeltPåkrevdVerdi
nameneiEn menneskelig etikett for regelen. Fritekst; har ingen effekt på evalueringen.
accessjaallow eller deny.
operationsjaIkke-tom liste med operasjonsmønstre (se Operasjoner).
targetsjaIkke-tom liste med FRN-mønstre (se Mål — FRN).
constraintsneiEkstra betingelser som må holde (se Betingelser).

schemaVersion er strengen "1". Skjemaet er append-only og versjonert som resten av plattformkontrakten — nye funksjoner legges til, aldri omdøpt eller fjernet, slik at en policy du skriver i dag fortsetter å fungere.

Operasjoner ​

En operasjon navngir én handling i formatet service:resource:action, for eksempel compute:instances:create eller storage:volumes:delete. Hvert segment godtar *-jokertegnet, og jokertegn kollapser på hvert nivå:

  • compute:instances:create — én eksakt operasjon
  • compute:instances:* — alle handlinger på compute-instanser
  • compute:* — alle compute-operasjoner
  • *:*:delete — alle sletthandlinger, på tvers av alle tjenester

Settet av konkrete operasjoner er en server-eid, append-only-katalog — ikke hardkod det, fordi det vokser over tid. Hent den live katalogen:

bash
fm iam catalog                 # all operations
fm iam catalog --filter compute   # only those containing "compute"

eller over HTTP:

bash
curl -H "Authorization: Bearer $TOKEN" \
  https://api.frostmoln.cloud/api/v1/tenants/$TENANT_ID/iam/catalog
# → { "operations": ["billing:invoices:create", "compute:instances:create", ... ] }

Portalens policy-bygger presenterer den samme katalogen som en velger.

Mål — FRN ​

Mål matches mot et Frostmoln Resource Name (FRN) — plattformens ressursnavngivingsskjema, analogt med et AWS ARN:

frn:<service>:<region>:<tenant>:<type>/<id>

I en regels targets skriver du FRN-mønstre, ved å bruke * for å bruke jokertegn på et hvilket som helst segment:

  • * — matcher alle ressurser (bruk sparsomt)
  • frn:compute:*:*:instances/* — enhver compute-instans, denne tenantens
  • frn:storage:*:*:volumes/* — ethvert volum, denne tenantens
  • frn:compute:*:*:instances/i-0a1b2c3d — én bestemt instans

<region>-segmentet må være *

Regionsavgrensede policyer støttes ennå ikke: en forespørsel bærer ingen oppslått region, så et mål som navngir én kan ikke matches pålitelig. Skriv alltid * der — et mål med noe annet avvises når du lagrer policyen. Alle andre segmenter fungerer som beskrevet over.

<tenant>-segmentet er din tenant

La <tenant> stå som *: fordi hver forespørsel bærer din egen tenant, viser * allerede til din tenant og ingen annen. Du kan også skrive din egen tenant-id eksplisitt, men et mål som navngir en annen tenant avvises når du lagrer — det kunne aldri matche, så regelen ville i praksis ikke ha noen effekt.

Betingelser ​

Betingelser legger vilkår til en regel. En regels constraints er et map nøklet på operator, deretter på betingelsesnøkkel:

json
{
  "name": "read-staging-from-office",
  "access": "allow",
  "operations": ["compute:instances:read"],
  "targets": ["frn:compute:*:*:instances/*"],
  "constraints": {
    "ipInRange": { "frn:sourceIp": ["203.0.113.0/24"] },
    "equals": { "frn:resourceTag/env": "staging" }
  }
}

Betingelsesnøkler ​

NøkkelBetydning
frn:regionKan ikke brukes ennå. En forespørsel bærer ingen oppslått region, så nøkkelen kan aldri løses: et allow som bruker den gir aldri tilgang, og et deny som bruker den utløses i alle regioner. La den stå ubrukt.
frn:sourceIpKallerens kilde-IP.
frn:tenantTenant-id-en.
frn:principalTypePrincipal-typen: api_key eller workload_identity.
frn:currentTimeForespørselstidspunktet (for before/after).
frn:requestTag/<k>Verdien av forespørselstaggen <k>.
frn:resourceTag/<k>Verdien av taggen <k> på målressursen.

Operatorer og verdiformer ​

OperatorVerdiformMerknader
equalsen enkelt strengEksakt match.
notEqualsen enkelt strengNegert eksakt match.
likeen enkelt strengGlob-match (*-jokertegn).
ipInRangeen liste med CIDR-strengerBrukes med frn:sourceIp.
beforeet enkelt RFC3339-tidsstempelBrukes med frn:currentTime.
afteret enkelt RFC3339-tidsstempelBrukes med frn:currentTime.

ipInRange er den eneste operatoren som tar en liste; alle andre operatorer tar en enkelt skalar streng. En ukjent nøkkel eller operator, eller en verdi en betingelse ikke kan løse på forespørselstidspunktet, feiler lukket — betingelsen holder ikke (så et allow gir ikke tilgang), og et deny utløses fortsatt.

⚠️ En betingelse på et deny innsnevrer det ​

Dette er det aller viktigste å få riktig. Betingelser anvendes på samme måte på allow- og deny-regler: en regel matcher bare når dens betingelser holder. Så en betingelse på en deny-regel gjør at deny-en utløses bare når betingelsen er definitivt sann — og lar operasjonen være tillatt når betingelsen er definitivt usann. (En uavklart eller ukjent betingelse utløser likevel deny-en — fail-closed.)

  • For å forby en operasjon ubetinget, skriv en deny-regel uten betingelse.
  • For å begrense en tildeling (til en kilde-IP, et tidsvindu, en ressurstagg), plasser betingelsen på allow-regelen.
json
{
  "schemaVersion": "1",
  "rules": [
    {
      "name": "create-read-from-office",
      "access": "allow",
      "operations": ["compute:instances:create", "compute:instances:read"],
      "targets": ["frn:compute:*:*:instances/*"],
      "constraints": { "ipInRange": { "frn:sourceIp": ["203.0.113.0/24"] } }
    },
    {
      "name": "never-delete",
      "access": "deny",
      "operations": ["compute:instances:delete"],
      "targets": ["*"]
    }
  ]
}

allow-en er nettverksbegrenset av sin betingelse; deny-en er ubetinget, så sletting er alltid forbudt. En betingelse på det deny-et ville ha tillatt sletting når betingelsen var usann.

Forfatte en policy ​

Forfatt i portalen, med fm-CLI-en, eller med Terraform. En policy skrives én gang og deretter knyttes til en eller flere principaler.

Portal ​

Åpne IAM → Access Policies, velg New policy, og bruk den veiledede byggeren — velg operasjoner fra katalogen, legg til mål og betingelser, og bruk den innebygde testeren for å sjekke en forespørsel før du lagrer. Åpne deretter en principal (API-nøkkel eller workload identity) og knytt til policyen.

fm CLI ​

bash
# Create from a file, stdin, or inline JSON
fm iam policy create --name ci-compute-operator --document @policy.json
cat policy.json | fm iam policy create --name ci-compute-operator --document -

# List / inspect / update / delete
fm iam policy list
fm iam policy get <policy-id>
fm iam policy update <policy-id> --document @policy.json
fm iam policy delete <policy-id>

# Attach to a principal (api_key | workload_identity | group)
fm iam policy attach <policy-id> --type api_key --id <key-id>
fm iam policy detach <policy-id> --type api_key --id <key-id>

Terraform ​

Sett sammen dokumentet med frostmoln_iam_policy_document-datakilden (nativt vokabular — rule / access / operations / targets / constraint), opprett deretter policyen og knytt den til:

hcl
data "frostmoln_iam_policy_document" "ci" {
  # Restrict the grant with a constraint on the ALLOW rule.
  rule {
    name       = "create-read-from-office"
    access     = "allow"
    operations = ["compute:instances:create", "compute:instances:read"]
    targets    = ["frn:compute:*:*:instances/*"]

    constraint {
      operator = "ipInRange"
      key      = "frn:sourceIp"
      values   = ["203.0.113.0/24"]
    }
  }

  # Forbid delete unconditionally — a deny with NO constraint.
  rule {
    name       = "never-delete"
    access     = "deny"
    operations = ["compute:instances:delete"]
    targets    = ["*"]
  }
}

resource "frostmoln_iam_policy" "ci" {
  name        = "ci-compute-operator"
  description = "CI: create/read compute from the office network, never delete"
  document    = data.frostmoln_iam_policy_document.ci.json
}

resource "frostmoln_iam_policy_attachment" "ci_key" {
  policy_id     = frostmoln_iam_policy.ci.id
  attachee_type = "api_key" # or "workload_identity" / "group"
  attachee_id   = frostmoln_api_key.ci.id
}

ipInRange tar en liste med CIDR-er; hver annen operators values er et enkelt element. Datakilden avviser en flerverdiliste på enhver annen operator.

Grupper ​

For å knytte den samme policyen til flere principaler, opprett en gruppe, legg principaler til den, og knytt policyen til gruppen:

bash
fm iam group create --name ci-keys
fm iam group member add <group-id> --type api_key --id <key-id>
fm iam policy attach <policy-id> --type group --id <group-id>

Et medlem er en api_key eller en workload_identity; en policy knyttes til en api_key, en workload_identity eller en group.

For å gi de samme policyene til mennesker i stedet for nøkler, se Medlemsgrupper nedenfor.

Medlemsgrupper ​

Gruppene ovenfor samler maskinprinsipaler. Medlemsgrupper samler mennesker: en vaktgruppe eller et team av dataforvaltere kan settes opp til å arve minst-privilegium-tilganger som gruppe, i stedet for å opprette en tilpasset rolle per person. De snakker samme vokabular som alle tilgangspolicyer på denne siden — operasjoner, FRN-mål, betingelser — og de knytter de samme delte policydokumentene som maskingruppene ovenfor bruker.

Registrert, ikke håndhevet for mennesker ennå

Medlemsgrupper hører til hele organisasjonen i stedet for til én tenant: en organisasjons eier eller administrator administrerer dem.

I denne utgivelsen registreres policyene du knytter til en medlemsgruppe, men de konsulteres ikke ennå når en persons forespørsler vurderes — ingenting i dem får effekt for mennesker ennå. Medlemmene beholder nøyaktig det organisasjonsrollen deres gir, til tilgangspolicyvurdering for mennesker slås på for hele plattformen; etablerer du gruppene nå, går disse tildelingene live med den bryteren. Maskinprinsipaler påvirkes ikke av dette: tilgangspolicyer på API-nøkler og arbeidslastidentiteter vurderes allerede slik denne siden beskriver.

Du finner dem under Organisasjoner → organisasjonen din → Medlemsgrupper:

  1. Opprett en gruppe — et navn (unikt innen organisasjonen) og en valgfri beskrivelse. Navn kan ikke endres fra portalen ennå; slett gruppen og opprett den på nytt hvis du trenger et annet.
  2. Legg til medlemmer — velg fra organisasjonens medlemsliste. Enhver administrator kan legge til eller fjerne ethvert medlem, eieren inkludert; ingen kan legge til seg selv (portalen gjemmer den påloggede brukeren, og API-et avviser forsøket uansett).
  3. Knytt delte tilgangspolicyer — velg blant de delte policyene som er forfattet i organisasjonens tenants; du kan koble fra en når som helst. Gruppens medlemmer er satt opp til å arve alt disse policyene tillater, i tillegg til det organisasjonsrollen deres allerede gir — se nedenfor hva som får effekt i denne utgivelsen. (fm og Terraform kan ikke forfatte medlemsgrupper ennå; portalen er forfattingsflaten.)

Hva medlemsgrupper betyr for medlemmene ​

  • Grupper legger bare til — de tar aldri bort. Et medlem beholder rollens rettigheter, og hver tilknyttet policy vurderes oppå rollen, aldri i stedet for den. Det finnes ingen innstilling for medlemsgrupper som fjerner et medlems rollerettigheter.
  • Ingen nektelse for medlemsgrupper i v1. En deny-regel i en policy som er knyttet til en medlemsgruppe begrenser ikke mennesker, og i denne utgivelsen gir disse policyenes allow-regler ikke noe til mennesker heller — ingenting knyttet til en medlemsgruppe påvirker vurderingen for mennesker ennå. Når arvet autoritet blir aktiv, tildeler medlemsgrupper kun additivt; uttrykkelige nektelsesregler forblir et maskinprinsipal-spørsmål til en senere utgivelse. (Nektelsesregler i policyer for API-nøkler og arbeidslastidentiteter håndheves allerede i dag.)
  • Ingen tak ved kjøretid. Hvis to tilknyttede policyer begge tillater en operasjon, har et medlem den; det finnes ingen kjøretidssjekk på formen »gruppen kan aldri overstige rettighetene til administratoren som knyttet den«. Beskyttelsen ligger per dokument på knytningstidspunktet: en kobling som overstiger den knyttende administrators egne rettigheter avvises.
  • Ingenting å anvende. Portalen har ingen knapp for å anvende eller håndheve — plattformen styrer når arvet autoritet får effekt, og (når den er aktiv for mennesker) når en endring et medlem ved det medlemmets neste tokenvalidering: senest ved den gjeldende sesjonens neste tokenfornyelse.
  • Medlemskapet er varig. Medlemskapet overlever rolleendringer og suspensjoner: endrer du en persons organisasjonsrolle, følger gruppemedlemskapet med. (Et suspandert medlem mottar ingen autoritet i det hele tatt mens de er suspandert, uansett hva gruppene deres sier — men raden forblir i listen, så gå gjennom den ved degradering eller suspensjon.) Å fjerne noen fra organisasjonen stenger også av tilgangen deres.
  • Å slette en gruppe sletter den registrerte medlemskapen og policyknytningene for alle i den — medlemskap kaskader og koblingene fjernes, slik at medlemmene, når arvet autoritet er aktiv, umiddelbart mister det gruppen hadde gitt.

Sikkerhetsregler ​

Medlemsgrupper legger til rettigheter; sikkerhetsregler tar dem av bordet. En sikkerhetsregel fester en policy som kun inneholder nekningsregler på organisasjonsnivå — eller på én enhet i organisasjonens enhetsstruktur — og dens nekningsregler binder deretter alle under festepunktet, eieren inkludert. Det er gulvformen virksomhetsstyring spør om: "ingen rolle, ingen tildeling, ingen gruppejustering kan la noen lese disse ressursene eller slette disse tjenestene." Kun plattformens eget personale slipper en sikkerhetsregel, av design.

Registrerte baner, ikke håndhevet for mennesker ennå

Sikkerhetsregler deler medlemsgruppenes stilling: de festes og lagres i dag, og hva en sikkerhetsregel gjør for et persons kall følger den samme plattformvide bryteren som slår på evaluering av tilgangspolicys for mennesker — den samme som medlemsgruppavsnittet ovenfor venter på. Før den slår om i ditt miljø endrer en festet sikkerhetsregel ingenting for noen; når den gjør det, trår nekningen i kraft ved medlemmens neste tokenvalidering. Maskinprinsipaler (API-nøkler, arbeidsidentiteter) bindes aldri av sikkerhetsregler — dette er en menneskeakse.

Finn dem under Organisasjoner → din organisasjon → Sikkerhetsregler (samme eier-eller-admin-terskel som medlemsgrupper):

  1. Knytt en sikkerhetsregel — velg omfanget (Organisasjon binder alle; en enhet binder alt i dens gren av enhetstreet) og fest en policy som kun inneholder nekningsregler. Et dokument med tillatelsesregler avslås — en sikkerhetsregel må aldri lydløst tildele.
  2. Løsne — den eneste sankjonerte måten å fjerne et gulv på. Den revideres med aktørens navn, og medlemmenes tokens løses uten den ved neste validering.

Hva sikkerhetsregler betyr i praksis ​

  • Nektelse vinner, punkt. En sikkerhetsregels nektelse slår gruppepolicys, egendefinerte roller, forhåndsvalgte roller og lesetilgang. Eierens deknende * gir ingenting en sikkerhetsregel forbyr.
  • Forfatteren nekter konflikter før de finnes. Plattformen nekter (GUARDRAIL_CONFLICT) en sikkerhetsregel som overlapper noe organisasjonen allerede har gitt via en gruppe eller en egendefinert rolle — og nekter i den andre retningen en gruppefesting eller rolle_endring som ville kollidere med en stående sikkerhetsregel. Avslaget navngir operasjonen; å innsnevre tildelingen (eller løsne sikkerhetsregelen, som selv revideres) er veien tilbake. Plattformen er bevisst overforsiktig her: en nektelse festet til én presis ressurs kan avslå en bredere tildeling i samme familie til du deler dokumentet.
  • Det festede dokumentet er låst. Mens en policy er festet som sikkerhetsregel kan den ikke redigeres eller slettes via den vanlige policyflaten (GUARDRAIL_PINNED) — en lydløs redigering ville være en lydløs lempelse. Løsne først, rediger deretter; en organisasjonsenhet med en festet sikkerhetsregel kan heller ikke slettes.
  • Enheter følger sin festing. En sikkerhetsregel festet til en enhet når hver tenant i den — å flytte en tenant spør om ingenting og endrer ingenting på papir, men det som binder den ved neste tokenvalidering er hva enhetstreet nå sier.
  • Kun metadata. Sikkerhetsregler-fanen viser selve festingen — nivå, enhet, policy-id — aldri policyens innhold; reglene ligger på policyens egen flate.

Egendefinerte roller ​

Foruten de fire invitatsjonspresetene (viewer, member, billing, admin) kan en organisasjon bære egendefinerte roller: navngitte tillatelsessett fra samme family:action-katalog som alle tilgangspolicyene på denne siden. Rollene opprettes i dag via rolle-API-et (POST /tenants/{tenant_id}/roles — portalens velger viser dem, den oppretter dem ikke ennå).

Egendefinerte roller som invitasjonsplasser. Når organisasjonen har egne roller, tilbyr invitasjonsdialogens rollevelger dem ved siden av presetene. En slik rolle refereres til med id-en sin, må tilhøre din egen organisasjon og sjekkes på nytt når invitasjonen godtas. To tak beskytter tildelingen:

  • En admin kan bare tildele et sett de selv har — både når rollen opprettes og når noen inviteres inn i den. En rolle bredere enn tildeleren avslås (ROLE_EXCEEDS_PERMISSIONS).
  • Eierens * dekker alt, så en eier kan alltid tildele enhver rolle i organisasjonen.

Hva en egendefinert rolle betyr for innehaveren. Rollens sett følger med tokenet deres akkurat som et presets gjør. Der evaluering for mennesker er slått på — samme plattformbryter som medlemsgruppene ovenfor venter på — er det rollens sett motoren veier; til den tid endres ingenting for ressurskallene deres. Egendefinerte roller er alltid nivå 0 i forvaltningsstigen: de kan ikke tildeles eller endres via medlemsforvaltning (kun invitasjonsflyten plasserer noen i dem), men et medlem som innehar en er fremdeles fullt tilgjengelig for fjerning, suspensjon, gjenopptagelse og nedgradering — inneslutningsverbene en organisasjonsadmin allerede har.

Test før du lagrer ​

En feilforfattet policy har reelle tenner i produksjon, så test den først. Testeren (portalbyggeren, eller fm iam simulate) kjører et kandidatdokument mot en hypotetisk forespørsel og returnerer allow eller deny — den lagrer eller håndhever aldri noe:

bash
fm iam simulate --document @policy.json \
  --operation compute:instances:delete --target '*'
# → deny

fm iam simulate --document @policy.json \
  --operation compute:instances:read --target 'frn:compute:*:*:instances/*' \
  --source-ip 203.0.113.10
# → allow

Flagg for betingelseskontekst: --source-ip, --tenant, --principal-type, --request-tag key=value, --resource-tag key=value. Et utelatt betingelsesfelt behandles som uløst / feiler lukket, akkurat som i produksjon. (--region finnes også, men frn:region kan ikke brukes ennå — se Betingelsesnøkler.)

Migrere fra scoper ​

Dine eksisterende API-nøkkel-scoper (compute:read, storage:write, …) fungerer fortsatt — hver eldre scope evalueres som en tilsvarende syntetisert allow-policy, så det er null tvungen migrering. compute:read oppfører seg som et allow over compute read/list-operasjonene på frn:compute:*.

Du migrerer en nøkkel til en ekte minste-privilegium-policy når du ønsker noe scoper ikke kan uttrykke. For eksempel, ved å erstatte en bred compute:write-scope:

compute:write gir create og update og delete på enhver compute- ressurs, fra hvor som helst. En minste-privilegium-erstatning kan være:

json
{
  "schemaVersion": "1",
  "rules": [
    {
      "name": "create-and-update-from-office",
      "access": "allow",
      "operations": [
        "compute:instances:create",
        "compute:instances:update",
        "compute:instances:read",
        "compute:instances:list"
      ],
      "targets": ["frn:compute:*:*:instances/*"],
      "constraints": { "ipInRange": { "frn:sourceIp": ["203.0.113.0/24"] } }
    },
    {
      "name": "never-delete",
      "access": "deny",
      "operations": ["compute:instances:delete"],
      "targets": ["*"]
    }
  ]
}

Steg:

  1. Forfatt policyen (over) og test den med fm iam simulate mot operasjonene arbeidslasten din faktisk utfører.
  2. Knytt den til nøkkelen.
  3. Innsnevre scopene på nøkkelen (policyen er additiv; både den syntetiserte scope-policyen og din tilknyttede policy evalueres, og ethvert eksplisitt deny vinner). Fjern den brede compute:write-scopen når den tilknyttede policyen dekker det nøkkelen trenger.
  4. Kjør fm iam simulate på nytt (eller følg nøkkelen i portalen) for å bekrefte at tildelingene og nektelsene er som du forventer.

Fordi et eksplisitt deny overstyrer ethvert allow, holder never-delete-regelen over selv mens den eldre scopen fortsatt er til stede — en trygg måte å stramme inn en nøkkel før du er ferdig med å fjerne scopene dens.