Concept Artifact Specification

Definition

A Concept is a foundational building block of the CFSE world model. Concepts represent the "nouns" of your system: entities, resources, principals, credentials, and other logical units that participate in security-relevant operations.

Concepts are NOT implementation artifacts (classes, tables, services). A single concept may span multiple implementation components. Concepts capture how users and security analysts think about the system - one concept equals one distinct "thing" that matters for security analysis.

Schema: concept.schema.yaml


Required Fields

FieldTypeDescription
idConceptIDUnique identifier following pattern C-<SYSTEM>-<NAME>
namestringHuman-readable name using domain terminology
promisestringSingle sentence describing what the concept represents and its security significance
attributesAttribute[]Data properties with types, constraints, and security metadata
entry_pointsEntryPointID[]References to EP-* Entry Point artifacts owned by this concept
invariantsInvariantID[]List of invariant IDs (INV-*) that govern this concept

Optional Fields

FieldTypeDefaultDescription
statesStateMachine-Lifecycle states and transitions if concept has discrete states
how_it_worksstring-High-level description of internal mechanisms and potential implementation patterns
security_investigation_candidatesstring[]-Potential weaknesses, fragility points, or security areas worth exploring
statusArtifactStatusDRAFTLifecycle status: DRAFT, REVIEW, PLANNED, ACTIVE, DEPRECATED, ARCHIVED
versionstring-Semantic version (e.g., 1.0.0)

Field Details

promise

The promise is a single sentence that captures the essence of the concept. It should answer:

  • What is this thing?
  • What role does it play in security?
  • Why does it matter?

A good promise is specific enough to differentiate this concept from others, yet general enough to cover all instances.

Examples:

  • Good: "A user account that can authenticate, own resources, and perform actions within the shop system."
  • Bad: "A user." (Too vague)
  • Bad: "A database record in the users table with columns id, email, password_hash, created_at, and associated orders." (Implementation detail)

attributes

Attributes define the data properties of the concept. Each attribute includes:

PropertyRequiredDescription
nameYesAttribute name in snake_case
typeYesData type: string, integer, boolean, array, object, uuid, timestamp, enum
requiredNoWhether attribute must be present (default: true)
defaultNoDefault value when not set
sensitiveNoContains PII, secrets, or other sensitive data (default: false)
immutableNoCannot be changed after creation (default: false)
descriptionNoHuman-readable description
constraintsNoValidation constraints
enum_valuesNoAllowed values when type is enum

Security-relevant attributes should be marked with sensitive: true. This enables:

  • Proper handling in logs and error messages
  • Data classification for compliance
  • Encryption requirements identification

entry_points

Concepts list the entry points (surfaces) they own as references to Entry Point artifacts (EP-*).

The EP-* artifact is the single source of truth for surface metadata: method/protocol, path/pattern, tangible_locations, accepted inputs, and optional exposure inventory (exposes[]).

Concepts SHOULD:

  • Include every EP-* whose owner_concept is this concept.
  • Avoid duplicating method/path/locations here; keep them on the EP-* artifact.

Entry Point ID Convention (Recommended)

Entry Point IDs SHOULD follow this convention to keep ownership and traceability obvious:

EP-<SYSTEM>-<CONCEPT>-<CHANNEL>-<ACTION>[-<NN>]

  • Other artifacts SHOULD reference Entry Points by ID (never restate them as prose-only paths).

invariants

Invariants are referenced by ID only - never inline invariant logic in concept documents. This ensures:

  • Single source of truth for security rules
  • Consistent application across artifacts
  • Easier maintenance and updates

Correct:

yaml
invariants:
  - INV-SHOP-OWNER-ONLY
  - INV-SHOP-AUTH-REQUIRED

Incorrect:

yaml
invariants:
  - rule: "Only owners can delete their items"
    logic: "FORALL item: C-SHOP-ITEM. DELETE(user, item) IMPLIES user.id == item.owner_id"

how_it_works

A high-level description of how the concept operates internally. This is NOT implementation code, but rather a logical summary of:

  • The underlying mechanism or algorithm
  • Key implementation patterns or approaches
  • How the concept achieves its security properties

This field helps analysts understand the concept deeply enough to identify potential security weaknesses.

Examples:

  • Good: "Authentication tokens are generated using HMAC-SHA256 with a server-side secret. Tokens include the user ID, expiration timestamp, and a nonce. Validation checks signature integrity, expiration, and revocation status against a Redis blacklist."
  • Bad: "Uses JWT." (Too vague)
  • Bad: The actual source code (Implementation detail)

security_investigation_candidates

A bullet-point list of potential security areas worth exploring for this concept. These are hypotheses about what could go wrong - they feed directly into invariant definition and scenario creation.

Each candidate should identify:

  • A potential weakness or fragility point
  • Why it might be exploitable
  • What type of attack it might enable

Examples:

yaml
security_investigation_candidates:
  - "Token expiration bypass - what if system clock is manipulated?"
  - "Race condition in balance updates - concurrent purchases might overdraw"
  - "Email verification bypass - can unverified accounts access protected resources?"
  - "Role escalation through parameter tampering - is role validated server-side?"

Key Patterns

  • One concept = one logical entity. If users think of "User" and "Admin" as the same kind of thing with different permissions, they are one concept with a role attribute, not two concepts.

  • Attributes reflect security-relevant state. Include attributes that affect authorization decisions, audit requirements, or data sensitivity - not every database column.

  • Entry points map to attack surface. Each entry point is a potential target for security testing. Document all ways to interact with the concept.

  • Invariants govern, concepts don't. Concepts reference invariants; they don't define security rules. Keep concepts as "data models" and invariants as "security policies."


Common Mistakes

MistakeProblemFix
[ ] Creating concepts for user rolesRoles are attributes of a User concept, not separate conceptsUse a role enum attribute on the User concept
[ ] Inlining invariant logicViolates single source of truth, makes maintenance hardExtract to invariant library (see artifacts/supporting/invariant_library/invariant_library.md), reference by INV-* ID
[ ] Omitting sensitive markersSecurity-relevant data not properly classifiedMark PII, secrets, and credentials with sensitive: true
[ ] Implementation-focused attributesConcept becomes tied to specific implementationFocus on logical properties, not database columns
[ ] Missing entry pointsIncomplete attack surface documentationAudit all APIs that touch this concept

Example: C-SHOP-USER

yaml
id: C-SHOP-USER
name: "Shop User"
promise: >
  A user account that can authenticate, own items for sale, and purchase
  items from other users within the shop marketplace.
 
attributes:
  - name: id
    type: uuid
    immutable: true
    description: "Unique identifier for the user"
 
  - name: email
    type: string
    sensitive: true
    description: "User's email address, used for authentication and notifications"
    constraints:
      - type: pattern
        value: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
 
  - name: password_hash
    type: string
    sensitive: true
    description: "Bcrypt hash of user's password"
 
  - name: role
    type: enum
    enum_values:
      - buyer
      - seller
      - admin
    default: buyer
    description: "User's role determining available actions"
 
  - name: verified
    type: boolean
    default: false
    description: "Whether email has been verified"
 
  - name: created_at
    type: timestamp
    immutable: true
    description: "Account creation timestamp"
 
  - name: balance
    type: integer
    default: 0
    description: "Account balance in cents"
    constraints:
      - type: range
        min: 0
        message: "Balance cannot be negative"
 
entry_points:
  - EP-USER-CREATE
  - EP-USER-READ
  - EP-USER-UPDATE
  - EP-USER-DELETE
 
invariants:
  - INV-SHOP-AUTH-REQUIRED
  - INV-SHOP-OWNER-ONLY
  - INV-SHOP-ADMIN-OVERRIDE
  - INV-SHOP-EMAIL-UNIQUE
  - INV-SHOP-BALANCE-NON-NEGATIVE
 
states:
  states:
    - name: PENDING
      description: "Account created but email not verified"
    - name: ACTIVE
      description: "Email verified, account fully functional"
    - name: SUSPENDED
      description: "Account suspended by admin"
    - name: DELETED
      description: "Account soft-deleted"
      terminal: true
  initial: PENDING
  transitions:
    - from: PENDING
      to: ACTIVE
      trigger: I-SHOP-VERIFY-EMAIL-001
    - from: ACTIVE
      to: SUSPENDED
      trigger: I-SHOP-SUSPEND-USER-001
      guard: INV-SHOP-ADMIN-ONLY
    - from: SUSPENDED
      to: ACTIVE
      trigger: I-SHOP-UNSUSPEND-USER-001
      guard: INV-SHOP-ADMIN-ONLY
    - from: ACTIVE
      to: DELETED
      trigger: I-SHOP-DELETE-USER-001
      guard: INV-SHOP-OWNER-ONLY
    - from: SUSPENDED
      to: DELETED
      trigger: I-SHOP-DELETE-USER-001
      guard: INV-SHOP-ADMIN-ONLY
 
how_it_works: |
  User accounts are stored in PostgreSQL with bcrypt-hashed passwords. Authentication
  uses session tokens stored in Redis with 24-hour expiration. Email verification
  generates a signed token (HMAC-SHA256) with 48-hour validity. Balance updates use
  database transactions with row-level locking to prevent race conditions.
 
security_investigation_candidates:
  - "Session fixation - can an attacker force a known session ID?"
  - "Password reset token reuse - are tokens invalidated after use?"
  - "Balance race condition - do concurrent purchases properly lock?"
  - "Email verification bypass - can unverified accounts access protected resources?"
  - "Role parameter injection - is role validated server-side on registration?"
  - "Account enumeration via timing - do login/reset responses leak existence?"
 
status: ACTIVE
version: "1.2.0"

Validation Criteria

A valid concept artifact MUST:

  1. Have a unique ID matching pattern C-<SYSTEM>-<NAME>
  2. Have a non-empty promise that describes security significance
  3. Have at least one attribute with valid type
  4. Have at least one entry point referencing an EP-* artifact
  5. Reference only valid invariant IDs (no inline logic)
  6. Use snake_case for attribute names
  7. Use UPPER_SNAKE_CASE for state names (if states are defined)
  8. Have valid state transitions where from/to reference defined states


Common Pitfalls

  • Modeling implementation objects (tables/services/classes) instead of security-relevant “nouns”.
  • Duplicating surface metadata (method/path/URLs) in Concepts instead of referencing EP-*.
  • Inlining invariant logic inside Concepts instead of referencing INV-* IDs.